package mods.eln.gridnode; import mods.eln.Eln; import mods.eln.misc.Coordonate; import mods.eln.misc.Direction; import mods.eln.misc.INBTTReady; import mods.eln.node.NodeManager; import mods.eln.node.transparent.TransparentNodeElement; import mods.eln.sim.ElectricalConnection; import mods.eln.sim.ElectricalLoad; import mods.eln.sim.mna.misc.MnaConst; import mods.eln.sixnode.electricalcable.ElectricalCableDescriptor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import java.util.HashSet; import java.util.Optional; /** * Created by svein on 23/08/15. */ public class GridLink implements INBTTReady { Coordonate a = new Coordonate(), b = new Coordonate(); boolean connected = false; // Drop this if the link is broken. ItemStack cable; private Direction as; private Direction bs; private Optional<GridElement> ae = Optional.empty(); private Optional<GridElement> be = Optional.empty(); private ElectricalConnection ab; private double rs = MnaConst.highImpedance; public GridLink(Coordonate a, Coordonate b, Direction as, Direction bs, ItemStack cable, double rs) { this.rs = rs; assert a != null && b != null && as != null && bs != null && cable != null; this.a = a; this.b = b; this.as = as; this.bs = bs; this.cable = cable; } public GridLink(NBTTagCompound nbt, String str) { readFromNBT(nbt, str); } public static GridElement getElementFromCoordinate(Coordonate coord) { if (coord == null) return null; TransparentNodeElement element = NodeManager.instance.getTransparentNodeFromCoordinate(coord); if (element instanceof GridElement) { return (GridElement) element; } else { return null; } } static public boolean addLink(GridElement a, GridElement b, Direction as, Direction bs, ElectricalCableDescriptor cable, int cableLength) { // Check if these two nodes are already linked. for (GridLink link : a.gridLinkList) { if (link.links(a, b)) { return false; } } for (GridLink link : b.gridLinkList) { if (link.links(a, b)) { return false; } } // Makin' a Link. Where'd Zelda go? GridLink link = new GridLink( a.coordonate(), b.coordonate(), as, bs, cable.newItemStack(cableLength), cable.electricalRs * cableLength); link.connect(); return true; } public GridElement elementA() { if (!ae.isPresent()) { ae = Optional.of(getElementFromCoordinate(a)); } return ae.get(); } public GridElement elementB() { if (!be.isPresent()) { be = Optional.of(getElementFromCoordinate(b)); } return be.get(); } public boolean connect() { GridElement a = getElementFromCoordinate(this.a); GridElement b = getElementFromCoordinate(this.b); if (a == null || b == null || connected) { return false; } // Add link to simulator. ElectricalLoad aLoad = a.getGridElectricalLoad(as); ElectricalLoad bLoad = b.getGridElectricalLoad(bs); assert aLoad != null; assert bLoad != null; assert ab == null; ab = new ElectricalConnection(aLoad, bLoad); Eln.simulator.addElectricalComponent(ab); ab.setR(rs); // Add link to link lists. a.gridLinkList.add(this); b.gridLinkList.add(this); updateElement(a); updateElement(b); connected = true; return true; } private void updateElement(GridElement e) { e.updateIdealRenderAngle(); // Need to also publish everything connected to this. HashSet<GridElement> s = new HashSet<GridElement>(); s.add(e); for (GridLink link : e.gridLinkList) { s.add(link.elementA()); s.add(link.elementB()); } for (GridElement element : s) { element.needPublish(); } } public void disconnect() { if (!connected) return; GridElement a = getElementFromCoordinate(this.a); GridElement b = getElementFromCoordinate(this.b); Eln.simulator.removeElectricalComponent(ab); ab = null; updateElement(a); updateElement(b); connected = false; } private boolean links(GridElement a, GridElement b) { if (this.a.equals(a.coordonate())) { return this.b.equals(b.coordonate()); } if (this.a.equals(b.coordonate())) { return this.b.equals(a.coordonate()); } return false; } @Override public void readFromNBT(NBTTagCompound nbt, String str) { a.readFromNBT(nbt, str + "a"); b.readFromNBT(nbt, str + "b"); as = Direction.readFromNBT(nbt, str + "as"); bs = Direction.readFromNBT(nbt, str + "bs"); rs = nbt.getDouble(str + "rs"); cable = ItemStack.loadItemStackFromNBT(nbt); } @Override public void writeToNBT(NBTTagCompound nbt, String str) { a.writeToNBT(nbt, str + "a"); b.writeToNBT(nbt, str + "b"); as.writeToNBT(nbt, str + "as"); bs.writeToNBT(nbt, str + "bs"); nbt.setDouble(str + "rs", rs); cable.writeToNBT(nbt); } public void selfDestroy() { onBreakElement(); } public ItemStack onBreakElement() { GridElement a = getElementFromCoordinate(this.a); GridElement b = getElementFromCoordinate(this.b); a.gridLinkList.remove(this); b.gridLinkList.remove(this); disconnect(); return cable; } public Direction getSide(GridElement gridElement) { if (gridElement == elementA()) { return as; } else { return bs; } } public GridElement getOtherElement(GridElement gridElement) { if (gridElement == elementA()) { return elementB(); } else { return elementA(); } } }