package mods.eln.sixnode.lampsupply; 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.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.VoltageStateWatchDog; import mods.eln.sim.process.destruct.WorldExplosion; import mods.eln.sixnode.electricalcable.ElectricalCableDescriptor; import mods.eln.sixnode.wirelesssignal.IWirelessSignalSpot; import mods.eln.sixnode.wirelesssignal.IWirelessSignalTx; import mods.eln.sixnode.wirelesssignal.WirelessUtils; import mods.eln.sixnode.wirelesssignal.aggregator.BiggerAggregator; import mods.eln.sixnode.wirelesssignal.aggregator.IWirelessSignalAggregator; import mods.eln.sixnode.wirelesssignal.aggregator.SmallerAggregator; import mods.eln.sixnode.wirelesssignal.aggregator.ToogleAggregator; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; 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.*; public class LampSupplyElement extends SixNodeElement { public static class PowerSupplyChannelHandle { PowerSupplyChannelHandle(LampSupplyElement element, int id) { this.element = element; this.id = id; } public LampSupplyElement element; public int id; } public static final HashMap<String, ArrayList<PowerSupplyChannelHandle>> channelMap = new HashMap<String, ArrayList<PowerSupplyChannelHandle>>(); public LampSupplyDescriptor descriptor; public NbtElectricalLoad powerLoad = new NbtElectricalLoad("powerLoad"); public Resistor loadResistor; public IProcess lampSupplySlowProcess = new LampSupplySlowProcess(); private AutoAcceptInventoryProxy inventory = (new AutoAcceptInventoryProxy(new SixNodeElementInventory(1, 64, this))) .acceptIfIncrement(0, 64, ElectricalCableDescriptor.class); static class Entry { Entry(String powerChannel, String wirelessChannel, int aggregator) { this.powerChannel = powerChannel; this.wirelessChannel = wirelessChannel; this.aggregator = aggregator; } public String powerChannel; public String wirelessChannel; public int aggregator; } public ArrayList<Entry> entries = new ArrayList<Entry>(); VoltageStateWatchDog voltageWatchdog = new VoltageStateWatchDog(); public static final byte setPowerName = 1; public static final byte setWirelessName = 2; public static final byte setSelectedAggregator = 3; double RpStack = 0; boolean[] channelStates; IWirelessSignalAggregator[][] aggregators; @Override public IInventory getInventory() { if (inventory != null) return inventory.getInventory(); else return null; } @Override public Container newContainer(Direction side, EntityPlayer player) { return new LampSupplyContainer(player, inventory.getInventory()); } public LampSupplyElement(SixNode sixNode, Direction side, SixNodeDescriptor descriptor) { super(sixNode, side, descriptor); this.descriptor = (LampSupplyDescriptor) descriptor; loadResistor = new Resistor(powerLoad, null); electricalComponentList.add(loadResistor); loadResistor.highImpedance(); electricalLoadList.add(powerLoad); slowProcessList.add(lampSupplySlowProcess); slowProcessList.add(voltageWatchdog); voltageWatchdog .set(powerLoad) .set(new WorldExplosion(this).cableExplosion()); channelStates = new boolean[this.descriptor.channelCount]; aggregators = new IWirelessSignalAggregator[this.descriptor.channelCount][3]; for (int idx = 0; idx < this.descriptor.channelCount; idx++) { channelStates[idx] = false; entries.add(new Entry("", "", 2)); aggregators[idx][0] = new BiggerAggregator(); aggregators[idx][1] = new SmallerAggregator(); aggregators[idx][2] = new ToogleAggregator(); } } class LampSupplySlowProcess implements IProcess { double sleepTimer = 0; HashMap<String, HashSet<IWirelessSignalTx>> txSet = new HashMap<String, HashSet<IWirelessSignalTx>>(); HashMap<IWirelessSignalTx, Double> txStrength = new HashMap<IWirelessSignalTx, Double>(); @Override public void process(double time) { loadResistor.setR(1 / RpStack); RpStack = 0; sleepTimer -= time; if (sleepTimer < 0) { sleepTimer += Utils.rand(1.2, 2); IWirelessSignalSpot spot = WirelessUtils.buildSpot(LampSupplyElement.this.getCoordonate(), null, 0); WirelessUtils.getTx(spot, txSet, txStrength); } for (int idx = 0; idx < LampSupplyElement.this.descriptor.channelCount; idx++) { Entry e = entries.get(idx); if (e.wirelessChannel.equals("")) { channelStates[idx] = true; } else if (e.wirelessChannel.toLowerCase().equals("true")) { channelStates[idx] = true; } else if (e.wirelessChannel.toLowerCase().equals("false")) { channelStates[idx] = false; } else { HashSet<IWirelessSignalTx> txs = txSet.get(e.wirelessChannel); if (txs == null) { channelStates[idx] = false; } else { channelStates[idx] = LampSupplyElement.this.aggregators[idx][e.aggregator].aggregate(txs) >= 0.5; } } } } } static void channelRegister(LampSupplyElement tx, int id, String channel) { if (channel.equals("")) return; ArrayList<PowerSupplyChannelHandle> list = channelMap.get(channel); if (list == null) channelMap.put(channel, list = new ArrayList<PowerSupplyChannelHandle>()); list.add(new PowerSupplyChannelHandle(tx, id)); } static void channelRemove(LampSupplyElement tx, int id, String channel) { if (channel.equals("")) return; List<PowerSupplyChannelHandle> list = channelMap.get(channel); if (list == null) return; Iterator<PowerSupplyChannelHandle> i = list.iterator(); while (i.hasNext()) { PowerSupplyChannelHandle e = i.next(); // must be called before you can call i.remove() // Do something if (e.element == tx && e.id == id) i.remove(); } if (list.isEmpty()) channelMap.remove(channel); } @Override public ElectricalLoad getElectricalLoad(LRDU lrdu) { if (getInventory().getStackInSlot(LampSupplyContainer.cableSlotId) == null) return null; if (front == lrdu) return powerLoad; return null; } @Override public ThermalLoad getThermalLoad(LRDU lrdu) { return null; } @Override public int getConnectionMask(LRDU lrdu) { if (getInventory().getStackInSlot(LampSupplyContainer.cableSlotId) == null) return 0; 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>(); for (int i = 0; i < 3; ++i) { Entry e = entries.get(i); if (!e.powerChannel.isEmpty()) { info.put(I18N.tr("Channel") + " " + (i + 1), e.powerChannel + " = " + (channelStates[i] ? "\u00A7aON" : "\u00A7cOFF")); } } info.put(I18N.tr("Total power"), Utils.plotPower("", powerLoad.getU() * powerLoad.getI())); if (Eln.wailaEasyMode) { info.put(I18N.tr("Voltage"), Utils.plotVolt("", powerLoad.getU())); } return info; } @Override public String thermoMeterString() { return null; } @Override public void initialize() { setupFromInventory(); } @Override protected void inventoryChanged() { super.inventoryChanged(); sixNode.disconnect(); setupFromInventory(); sixNode.connect(); needPublish(); } @Override public boolean onBlockActivated(EntityPlayer entityPlayer, Direction side, float vx, float vy, float vz) { if (onBlockActivatedRotate(entityPlayer)) return true; return inventory.take(entityPlayer.getCurrentEquippedItem(), this, false, true); } @Override public void destroy(EntityPlayerMP entityPlayer) { super.destroy(entityPlayer); unregister(); } @Override public void unload() { super.unload(); unregister(); } void unregister() { int idx = 0; for (Entry e : entries) channelRemove(this, idx++, e.powerChannel); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); int idx = 0; for (Entry e : entries) { nbt.setString("entry_p" + idx, e.powerChannel); nbt.setString("entry_w" + idx, e.wirelessChannel); nbt.setBoolean("channelStates" + idx, channelStates[idx]); nbt.setInteger("selectedAggregator" + idx, e.aggregator); ((ToogleAggregator) aggregators[idx][2]).writeToNBT(nbt, "toogleAggregator" + idx); idx++; } } @Override public void readFromNBT(NBTTagCompound nbt) { int idx = 0; for (Entry e : entries) { channelRemove(this, idx++, e.powerChannel); } super.readFromNBT(nbt); if (nbt.hasKey("channel")) { entries.get(0).powerChannel = nbt.getString("channel"); } else { idx = 0; while (nbt.hasKey("entry_p" + idx)) { entries.set(idx, new Entry(nbt.getString("entry_p" + idx), nbt.getString("entry_w" + idx), nbt.getInteger("selectedAggregator" + idx))); channelStates[idx] = nbt.getBoolean("channelStates" + idx); ((ToogleAggregator) aggregators[idx][2]).readFromNBT(nbt, "toogleAggregator" + idx); idx++; } } idx = 0; for (Entry e : entries) { channelRegister(this, idx++, e.powerChannel); } } void setupFromInventory() { ItemStack cableStack = getInventory().getStackInSlot(LampSupplyContainer.cableSlotId); if (cableStack != null) { ElectricalCableDescriptor desc = (ElectricalCableDescriptor) ElectricalCableDescriptor.getDescriptor(cableStack); desc.applyTo(powerLoad); voltageWatchdog.setUNominal(desc.electricalNominalVoltage); } else { voltageWatchdog.setUNominal(10000); powerLoad.highImpedance(); } } @Override public void networkUnserialize(DataInputStream stream) { super.networkUnserialize(stream); try { switch (stream.readByte()) { case setPowerName: { int id = stream.readByte(); String newName = stream.readUTF(); channelRemove(this, id, entries.get(id).powerChannel); entries.get(id).powerChannel = newName; needPublish(); channelRegister(this, id, newName); break; } case setWirelessName: { int id = stream.readByte(); String newName = stream.readUTF(); channelRemove(this, id, entries.get(id).wirelessChannel); entries.get(id).wirelessChannel = newName; needPublish(); channelRegister(this, id, newName); break; } case setSelectedAggregator: entries.get(stream.readByte()).aggregator = stream.readByte(); needPublish(); break; } } catch (IOException e) { e.printStackTrace(); } } @Override public boolean hasGui() { return true; } @Override public void networkSerialize(DataOutputStream stream) { super.networkSerialize(stream); try { for (Entry e : entries) { stream.writeUTF(e.powerChannel); stream.writeUTF(e.wirelessChannel); stream.writeChar(e.aggregator); } Utils.serialiseItemStack(stream, getInventory().getStackInSlot(LampSupplyContainer.cableSlotId)); } catch (IOException e) { e.printStackTrace(); } } public void addToRp(double r) { RpStack += 1 / r; } public boolean getChannelState(int channel) { return channelStates[channel]; } public int getRange() { return getRange(descriptor, inventory.getInventory()); } private int getRange(LampSupplyDescriptor desc, IInventory inventory2) { ItemStack stack = getInventory().getStackInSlot(LampSupplyContainer.cableSlotId); if (stack == null) return desc.range; return desc.range + stack.stackSize; } }