/// <summary> /// Binds the provided CommNetwork to the current CommNetManagerNetwork instance. /// </summary> /// <param name="bind">The derived CommNetwork instance which should be bound to CommNetManagerNetwork.</param> /// <returns>True if succesful at binding, false if not.</returns> /// <remarks> /// This method links the protected fields inherited from CommNet.Network.Net<para /> /// <list type="bullet"> /// <listheader><description>CAUTION: When bound to CommNetManager, you should ensure the following methods do not call base.method():<para /></description></listheader> /// <item><description>Add</description></item> /// <item><description>Remove</description></item> /// <item><description>Connect</description></item> /// <item><description>Disconnect</description></item> /// <item><description>Rebuild</description></item> /// </list> /// </remarks> public static bool BindToCommNetManager(CommNetwork bind) { CommNetwork CommNetManagerInstance = GetCommNetManagerNetwork(); if (CommNetManagerInstance == null) { return(false); } if (BindTo_method == null) { BindTo_method = CommNetManager.GetMethod("BindNetwork", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); } return((bool)BindTo_method.Invoke(CommNetManagerInstance, new object[] { bind })); }
public bool BindNetwork(CommNetwork net) { // Use reflection to force the network to use this network's associated Lists try { Type netType = net.GetType(); netType.GetField("candidates", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.candidates); netType.GetField("links", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.links); netType.GetField("nodeEnum", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.nodeEnum); netType.GetField("nodeLink", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.nodeLink); netType.GetField("nodeLinkEnum", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.nodeLinkEnum); netType.GetField("nodes", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.nodes); netType.GetField("occluders", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(net, this.occluders); return(true); } catch { return(false); } }
private bool isOccluded(CommNode a, CommNode b, double dist, CommNetwork net) { bool?occlusion = null; try { occlusion = _occlusionMethod.Invoke( net, new object[] { a.precisePosition, a.occluder, b.precisePosition, b.occluder, dist } ) as bool?; } catch (Exception e) { RelayLog("Error in assessing occlusion for science relay...\n{0}", e); return(true); } if (occlusion == null) { return(true); } return(!(bool)occlusion); }
public BeaconCommNetwork() { realNet = CommNetManagerChecker.GetCommNetManagerNetwork(); }
/// <summary> /// Overrode UpdateDisplay() fully and add own customisations /// </summary> private void updateCustomisedView() { if (FlightGlobals.ActiveVessel == null) { this.useTSBehavior = true; } else { this.useTSBehavior = false; this.vessel = FlightGlobals.ActiveVessel; } if (this.vessel == null || this.vessel.connection == null || this.vessel.connection.Comm.Net == null) //revert to default display mode if saved mode is inconsistent in current situation { this.useTSBehavior = true; if (CustomModeTrackingStation != CustomDisplayMode.None) { if (CustomModeTrackingStation != CustomDisplayMode.Network && CustomModeTrackingStation != CustomDisplayMode.MultiPaths) { CustomModeTrackingStation = CustomDisplayMode.Network; ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_118264", new string[] { Localizer.Format(CustomModeTrackingStation.displayDescription()) }), 5f); } } } if (this.useTSBehavior) { CNVCommNetUI.CustomMode = CNVCommNetUI.CustomModeTrackingStation; } else { CNVCommNetUI.CustomMode = CNVCommNetUI.CustomModeFlightMap; } CommNetwork net = CommNetNetwork.Instance.CommNet; CommNetVessel cnvessel = null; CommNode node = null; CommPath path = null; if (this.vessel != null && this.vessel.connection != null && this.vessel.connection.Comm.Net != null) { cnvessel = this.vessel.connection; node = cnvessel.Comm; path = cnvessel.ControlPath; } //work out which links to display int count = this.points.Count;//save previous value int numLinks = 0; switch (CNVCommNetUI.CustomMode) { case CNVCommNetUI.CustomDisplayMode.None: numLinks = 0; break; case CNVCommNetUI.CustomDisplayMode.FirstHop: case CNVCommNetUI.CustomDisplayMode.Path: if (cnvessel.ControlState == VesselControlState.Probe || cnvessel.ControlState == VesselControlState.Kerbal || path.Count == 0) { numLinks = 0; } else { if (CNVCommNetUI.CustomMode == CNVCommNetUI.CustomDisplayMode.FirstHop) { path.First.GetPoints(this.points); numLinks = 1; } else { path.GetPoints(this.points, true); numLinks = path.Count; } } break; case CNVCommNetUI.CustomDisplayMode.VesselLinks: numLinks = node.Count; node.GetLinkPoints(this.points); break; case CNVCommNetUI.CustomDisplayMode.Network: if (net.Links.Count == 0) { numLinks = 0; } else { numLinks = net.Links.Count; net.GetLinkPoints(this.points); } break; case CNVCommNetUI.CustomDisplayMode.MultiPaths: if (net.Links.Count == 0) { numLinks = 0; } else { CommPath newPath = new CommPath(); var nodes = net; var vessels = FlightGlobals.fetch.vessels; for (int i = 0; i < vessels.Count; i++) { var commnetvessel = vessels[i].connection; if (commnetvessel == null) // like flag { continue; } SetPrivatePropertyValue <CommNetVessel>(commnetvessel, "unloadedDoOnce", true); //network update is done only once for unloaded vessels so need to manually re-trigger every time //don't want to override CommNetVessel to just set the boolean flag if (!(commnetvessel.ControlState == VesselControlState.Probe || commnetvessel.ControlState == VesselControlState.Kerbal || commnetvessel.ControlPath == null || commnetvessel.ControlPath.Count == 0)) { for (int pathIndex = 0; pathIndex < commnetvessel.ControlPath.Count; pathIndex++) { var link = commnetvessel.ControlPath[pathIndex]; if (newPath.Find(x => x.a.precisePosition == link.a.precisePosition && x.b.precisePosition == link.b.precisePosition) == null) //not found in list of links to be displayed { newPath.Add(link); //laziness wins //KSP techincally does not care if path is consisted of non-continuous links or not } } } } path = newPath; path.GetPoints(this.points, true); numLinks = path.Count; } break; }// end of switch //check if nothing to display if (numLinks == 0) { if (this.line != null) { this.line.active = false; } this.points.Clear(); return; } if (this.line != null) { this.line.active = true; } else { this.refreshLines = true; } ScaledSpace.LocalToScaledSpace(this.points); //seem very important if (this.refreshLines || MapView.Draw3DLines != this.draw3dLines || count != this.points.Count || this.line == null) { this.CreateLine(ref this.line, this.points);//seems it is multiple separate lines not single continuous line this.draw3dLines = MapView.Draw3DLines; this.refreshLines = false; } //paint the links switch (CNVCommNetUI.CustomMode) { case CNVCommNetUI.CustomDisplayMode.FirstHop: { float lvl = Mathf.Pow((float)path.First.signalStrength, this.colorLerpPower); if (this.swapHighLow) { this.line.SetColor(Color.Lerp(this.colorHigh, this.colorLow, lvl), 0); } else { this.line.SetColor(Color.Lerp(this.colorLow, this.colorHigh, lvl), 0); } break; } case CNVCommNetUI.CustomDisplayMode.Path: case CNVCommNetUI.CustomDisplayMode.MultiPaths: { int linkIndex = numLinks; for (int i = linkIndex - 1; i >= 0; i--) { float lvl = Mathf.Pow((float)path[i].signalStrength, this.colorLerpPower); if (this.swapHighLow) { this.line.SetColor(Color.Lerp(this.colorHigh, this.colorLow, lvl), i); } else { this.line.SetColor(Color.Lerp(this.colorLow, this.colorHigh, lvl), i); } } break; } case CNVCommNetUI.CustomDisplayMode.VesselLinks: { var itr = node.Values.GetEnumerator(); int linkIndex = 0; while (itr.MoveNext()) { CommLink link = itr.Current; float lvl = Mathf.Pow((float)link.GetSignalStrength(link.a != node, link.b != node), this.colorLerpPower); if (this.swapHighLow) { this.line.SetColor(Color.Lerp(this.colorHigh, this.colorLow, lvl), linkIndex++); } else { this.line.SetColor(Color.Lerp(this.colorLow, this.colorHigh, lvl), linkIndex++); } } break; } case CNVCommNetUI.CustomDisplayMode.Network: { for (int i = numLinks - 1; i >= 0; i--) { CommLink commLink = net.Links[i]; float lvl = Mathf.Pow((float)net.Links[i].GetBestSignal(), this.colorLerpPower); if (this.swapHighLow) { this.line.SetColor(Color.Lerp(this.colorHigh, this.colorLow, lvl), i); } else { this.line.SetColor(Color.Lerp(this.colorLow, this.colorHigh, lvl), i); } } break; } } // end of switch if (this.draw3dLines) { this.line.SetWidth(this.lineWidth3D); this.line.Draw3D(); } else { this.line.SetWidth(this.lineWidth2D); this.line.Draw(); } }
private List <KeyValuePair <Vessel, double> > getConnectedVessels(Vessel v) { List <KeyValuePair <Vessel, double> > connections = new List <KeyValuePair <Vessel, double> >(); List <KeyValuePair <CommNode, double> > checkNodes = new List <KeyValuePair <CommNode, double> >(); if (v.connection != null) { CommNode source = v.connection.Comm; if (source != null) { if (!settings.requireRelay) { checkNodes.Add(new KeyValuePair <CommNode, double>(source, 1)); } CommNetwork net = v.connection.Comm.Net; if (net != null) { for (int i = FlightGlobals.Vessels.Count - 1; i >= 0; i--) { Vessel otherVessel = FlightGlobals.Vessels[i]; if (otherVessel == null) { continue; } if (otherVessel == v) { continue; } VesselType type = otherVessel.vesselType; if (type == VesselType.Debris || type == VesselType.SpaceObject || type == VesselType.Unknown || type == VesselType.Flag) { continue; } if (otherVessel.connection == null || otherVessel.connection.Comm == null) { continue; } if (!net.FindPath(source, pathCache, otherVessel.connection.Comm)) { continue; } if (pathCache == null) { continue; } if (pathCache.Count <= 0) { continue; } if (!settings.requireRelay) { double totalStrength = 1; int l = pathCache.Count; for (int j = 0; j < l; j++) { CommLink link = pathCache[j]; totalStrength *= link.signalStrength; if (!link.a.isHome && !updateCommNode(checkNodes, link.a, totalStrength)) { checkNodes.Add(new KeyValuePair <CommNode, double>(link.a, totalStrength)); } if (!link.b.isHome && !updateCommNode(checkNodes, link.b, totalStrength)) { checkNodes.Add(new KeyValuePair <CommNode, double>(link.b, totalStrength)); } } } if (settings.requireMPL && !VesselUtilities.VesselHasModuleName("ModuleScienceLab", otherVessel)) { continue; } if (!VesselUtilities.VesselHasModuleName("ModuleScienceContainer", otherVessel)) { continue; } double s = pathCache.signalStrength; s = source.scienceCurve.Evaluate(s); connections.Add(new KeyValuePair <Vessel, double>(otherVessel, s + 1)); } if (!settings.requireRelay) { for (int k = checkNodes.Count - 1; k >= 0; k--) { KeyValuePair <CommNode, double> pair = checkNodes[k]; CommNode node = pair.Key; if (node.isHome) { continue; } for (int l = FlightGlobals.Vessels.Count - 1; l >= 0; l--) { Vessel otherVessel = FlightGlobals.Vessels[l]; if (otherVessel == null) { continue; } if (otherVessel == v) { continue; } VesselType type = otherVessel.vesselType; if (type == VesselType.Debris || type == VesselType.SpaceObject || type == VesselType.Unknown || type == VesselType.Flag) { continue; } if (otherVessel.connection == null || otherVessel.connection.Comm == null) { continue; } CommNode otherComm = otherVessel.connection.Comm; if (otherComm.antennaRelay.power > 0) { continue; } if (settings.requireMPL && !VesselUtilities.VesselHasModuleName("ModuleScienceLab", otherVessel)) { continue; } if (!VesselUtilities.VesselHasModuleName("ModuleScienceContainer", otherVessel)) { continue; } double dist = (otherComm.precisePosition - node.precisePosition).magnitude; if (isOccluded(node, otherComm, dist, net)) { continue; } double power = directConnection(node, otherComm, dist, source == node, pair.Value); if (power <= 0) { continue; } power = source.scienceCurve.Evaluate(power); bool flag = false; for (int m = connections.Count - 1; m >= 0; m--) { KeyValuePair <Vessel, double> connect = connections[m]; if (connect.Key != otherVessel) { continue; } if (connect.Value < power + 1) { connections[m] = new KeyValuePair <Vessel, double>(connect.Key, power + 1); } flag = true; break; } for (int m = connections.Count - 1; m >= 0; m--) { KeyValuePair <Vessel, double> connect = connections[m]; if (connect.Key != otherVessel) { continue; } break; } if (!flag) { connections.Add(new KeyValuePair <Vessel, double>(otherVessel, power + 1)); } } } } } } } return(connections); }
/// <summary> /// Overrode UpdateDisplay() fully and add own customisations /// </summary> private void updateCustomisedView() { if (FlightGlobals.ActiveVessel == null) { this.useTSBehavior = true; } else { this.useTSBehavior = false; this.vessel = FlightGlobals.ActiveVessel; } if (this.vessel == null || this.vessel.connection == null || this.vessel.connection.Comm.Net == null) //revert to default display mode if saved mode is inconsistent in current situation { this.useTSBehavior = true; if (CustomModeTrackingStation != CustomDisplayMode.None) { if (CustomModeTrackingStation != CustomDisplayMode.Network && CustomModeTrackingStation != CustomDisplayMode.MultiPaths) { CustomModeTrackingStation = CustomDisplayMode.Network; ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_118264", new string[] { Localizer.Format(CustomModeTrackingStation.displayDescription()) }), CNCSettings.ScreenMessageDuration); } } } if (CommNetNetwork.Instance == null) { return; } if (this.useTSBehavior) { CNCCommNetUI.CustomMode = CNCCommNetUI.CustomModeTrackingStation; } else { CNCCommNetUI.CustomMode = CNCCommNetUI.CustomModeFlightMap; } CommNetwork net = CommNetNetwork.Instance.CommNet; CommNetVessel cnvessel = null; CommNode node = null; CommPath path = null; if (this.vessel != null && this.vessel.connection != null && this.vessel.connection.Comm.Net != null) { cnvessel = this.vessel.connection; node = cnvessel.Comm; path = cnvessel.ControlPath; } //work out which links to display int count = this.points.Count;//save previous value int numLinks = 0; bool pathLinkExist; switch (CNCCommNetUI.CustomMode) { case CNCCommNetUI.CustomDisplayMode.None: numLinks = 0; break; case CNCCommNetUI.CustomDisplayMode.FirstHop: if (cnvessel.ControlState != VesselControlState.Probe && cnvessel.ControlState != VesselControlState.Kerbal && path != null) { if (path.Count != 0) { path.First.GetPoints(this.points); numLinks = 1; break; } } numLinks = 0; break; case CNCCommNetUI.CustomDisplayMode.Path: if (cnvessel.ControlState != VesselControlState.Probe && cnvessel.ControlState != VesselControlState.Kerbal && path != null) { if (path.Count != 0) { path.GetPoints(this.points, true); numLinks = path.Count; break; } } numLinks = 0; break; case CNCCommNetUI.CustomDisplayMode.VesselLinks: numLinks = node.Count; node.GetLinkPoints(this.points); break; case CNCCommNetUI.CustomDisplayMode.Network: if (net.Links.Count == 0) { numLinks = 0; } else { //net.GetLinkPoints(this.points); //numLinks = net.Links.Count; //KSP 1.8: Likely shader changes led to stackup of 2 or more lines illustrating overall brighter line //Workaround: collect unqiue lines as path path = new CommPath(); path.Capacity = net.Links.Count; for (int i = 0; i < net.Links.Count; i++) { pathLinkExist = false; for (int overallpathIndex = 0; overallpathIndex < path.Count; overallpathIndex++) //check if path has this link already { if (CNCCommNetwork.AreSame(path[overallpathIndex].a, net.Links[i].a) && CNCCommNetwork.AreSame(path[overallpathIndex].b, net.Links[i].b)) { pathLinkExist = true; break; } } if (!pathLinkExist) { path.Add(net.Links[i]); } } path.GetPoints(this.points, true); numLinks = path.Count; } break; case CNCCommNetUI.CustomDisplayMode.MultiPaths: if (net.Links.Count == 0) { numLinks = 0; } else { path = new CommPath(); path.Capacity = net.Links.Count; for (int i = 0; i < net.Count; i++) { if (net[i].isControlSource) //is it ground station/remote-control pilot? { continue; } var thisPath = new CommPath(); net.FindHome(net[i], thisPath); for (int controlpathIndex = 0; controlpathIndex < thisPath.Count; controlpathIndex++) { pathLinkExist = false; for (int overallpathIndex = 0; overallpathIndex < path.Count; overallpathIndex++) //check if overall path has this link already { if (CNCCommNetwork.AreSame(path[overallpathIndex].a, thisPath[controlpathIndex].a) && CNCCommNetwork.AreSame(path[overallpathIndex].b, thisPath[controlpathIndex].b)) { pathLinkExist = true; break; } } if (!pathLinkExist) { path.Add(thisPath[controlpathIndex]); } } } path.GetPoints(this.points, true); numLinks = path.Count; } break; }// end of switch //check if nothing to display if (numLinks == 0) { if (this.line != null) { this.line.active = false; } this.points.Clear(); return; } if (this.line != null) { this.line.active = true; } else { this.refreshLines = true; } ScaledSpace.LocalToScaledSpace(this.points); //seem very important if (!(!this.refreshLines && MapView.Draw3DLines == this.draw3dLines && count == this.points.Count && this.line != null)) { this.CreateLine(ref this.line, this.points);//seems it is multiple separate lines not single continuous line this.draw3dLines = MapView.Draw3DLines; this.refreshLines = false; } //paint the links switch (CNCCommNetUI.CustomMode) { case CNCCommNetUI.CustomDisplayMode.FirstHop: { this.line.SetColor(colorBlending(getConstellationColor(path.First.a, path.First.b), this.colorLow, Mathf.Pow((float)path.First.signalStrength, this.colorLerpPower)), 0); break; } case CNCCommNetUI.CustomDisplayMode.Path: case CNCCommNetUI.CustomDisplayMode.MultiPaths: { for (int i = numLinks - 1; i >= 0; i--) { this.line.SetColor(colorBlending(getConstellationColor(path[i].a, path[i].b), this.colorLow, Mathf.Pow((float)path[i].signalStrength, this.colorLerpPower)), i); } break; } case CNCCommNetUI.CustomDisplayMode.VesselLinks: { CommLink[] links = new CommLink[node.Count]; node.Values.CopyTo(links, 0); for (int i = 0; i < links.Length; i++) { this.line.SetColor(colorBlending(getConstellationColor(links[i].a, links[i].b), this.colorLow, Mathf.Pow((float)links[i].GetSignalStrength(links[i].a != node, links[i].b != node), this.colorLerpPower)), i); } break; } case CNCCommNetUI.CustomDisplayMode.Network: { //for (int i = numLinks - 1; i >= 0; i--) //{ // this.line.SetColor(colorBlending(getConstellationColor(net.Links[i].a, net.Links[i].b), // this.colorLow, // Mathf.Pow((float) net.Links[i].GetBestSignal(), this.colorLerpPower)), // i); //} for (int i = numLinks - 1; i >= 0; i--) { this.line.SetColor(colorBlending(getConstellationColor(path[i].a, path[i].b), this.colorLow, Mathf.Pow((float)path[i].GetBestSignal(), this.colorLerpPower)), i); } break; } } // end of switch if (this.draw3dLines) { this.line.SetWidth(this.lineWidth3D); this.line.Draw3D(); } else { this.line.SetWidth(this.lineWidth2D); this.line.Draw(); } }
// Render the CommNet presentation // This method has been created to modify line color private void UpdateView() { CommNetwork net = CommNetNetwork.Instance.CommNet; CommNetVessel cnvessel = null; CommNode node = null; CommPath path = null; if (vessel != null && vessel.connection != null && vessel.connection.Comm.Net != null) { cnvessel = vessel.connection; node = cnvessel.Comm; path = cnvessel.ControlPath; } // Work out how many connections to paint int numLinks = 0; int count = points.Count; switch (Mode) { case DisplayMode.None: { numLinks = 0; break; } case DisplayMode.FirstHop: { if (cnvessel.ControlState == VesselControlState.Probe || cnvessel.ControlState == VesselControlState.Kerbal || path == null || path.Count == 0) { numLinks = 0; } else { path.First.GetPoints(points); numLinks = 1; } break; } case DisplayMode.Path: { if (cnvessel.ControlState == VesselControlState.Probe || cnvessel.ControlState == VesselControlState.Kerbal || path == null || path.Count == 0) { numLinks = 0; } else { path.GetPoints(points, true); numLinks = path.Count; } break; } case DisplayMode.VesselLinks: { numLinks = node.Count; node.GetLinkPoints(points); break; } case DisplayMode.Network: { if (net.Links.Count == 0) { numLinks = 0; } else { numLinks = net.Links.Count; net.GetLinkPoints(points); } break; } } // Check if nothing to draw if (numLinks == 0) { if (line != null) { line.active = false; } points.Clear(); return; } else { // TODO: I'm not sure if I need the commented part below. //if (line != null) line.active = true; //else refreshLines = true; //ScaledSpace.LocalToScaledSpace(points); //if (refreshLines || MapView.Draw3DLines != draw3dLines || (count != points.Count || line == null)) //{ // CreateLine(ref line, points); // draw3dLines = MapView.Draw3DLines; // refreshLines = false; //} //paint eligible connections // Sample to create a customHighColor : // Color customHighColor = getConstellationColor(path.First.a, path.First.b); // If want custom color, alter colorHigh for customHighColor switch (Mode) { case DisplayMode.FirstHop: { float lvl = Mathf.Pow((float)path.First.signalStrength, colorLerpPower); if (swapHighLow) { line.SetColor(Color.Lerp(colorHigh, colorLow, lvl), 0); } else { line.SetColor(Color.Lerp(colorLow, colorHigh, lvl), 0); } break; } case DisplayMode.Path: { int linkIndex = numLinks; for (int i = linkIndex - 1; i >= 0; i--) { float lvl = Mathf.Pow((float)path[i].signalStrength, colorLerpPower); if (swapHighLow) { line.SetColor(Color.Lerp(colorHigh, colorLow, lvl), i); } else { line.SetColor(Color.Lerp(colorLow, colorHigh, lvl), i); } } break; } case DisplayMode.VesselLinks: { var itr = node.Values.GetEnumerator(); int linkIndex = 0; while (itr.MoveNext()) { CommLink link = itr.Current; float lvl = Mathf.Pow((float)link.GetSignalStrength(link.a != node, link.b != node), colorLerpPower); if (swapHighLow) { line.SetColor(Color.Lerp(colorHigh, colorLow, lvl), linkIndex++); } else { line.SetColor(Color.Lerp(colorLow, colorHigh, lvl), linkIndex++); } } break; } case DisplayMode.Network: { int linkIndex = numLinks; while (linkIndex-- > 0) { CommLink commLink = net.Links[linkIndex]; float t2 = Mathf.Pow((float)net.Links[linkIndex].GetBestSignal(), colorLerpPower); if (swapHighLow) { line.SetColor(Color.Lerp(colorHigh, colorLow, t2), linkIndex); } else { line.SetColor(Color.Lerp(colorLow, colorHigh, t2), linkIndex); } } break; } } } }
/// <summary> /// Overrode UpdateDisplay() fully and add own customisations /// </summary> private void updateCustomisedView() { if (FlightGlobals.ActiveVessel == null) { this.useTSBehavior = true; } else { this.useTSBehavior = false; this.vessel = FlightGlobals.ActiveVessel; } if (this.vessel == null || this.vessel.connection == null || this.vessel.connection.Comm.Net == null) //revert to default display mode if saved mode is inconsistent in current situation { this.useTSBehavior = true; if (CustomModeTrackingStation != CustomDisplayMode.None) { if (CustomModeTrackingStation != CustomDisplayMode.Network && CustomModeTrackingStation != CustomDisplayMode.MultiPaths) { CustomModeTrackingStation = CustomDisplayMode.Network; ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_118264", new string[] { Localizer.Format(CustomModeTrackingStation.displayDescription()) }), CNCSettings.ScreenMessageDuration); } } } if (this.useTSBehavior) { CNCCommNetUI.CustomMode = CNCCommNetUI.CustomModeTrackingStation; } else { CNCCommNetUI.CustomMode = CNCCommNetUI.CustomModeFlightMap; } CommNetwork net = CommNetNetwork.Instance.CommNet; CommNetVessel cnvessel = null; CommNode node = null; CommPath path = null; if (this.vessel != null && this.vessel.connection != null && this.vessel.connection.Comm.Net != null) { cnvessel = this.vessel.connection; node = cnvessel.Comm; path = cnvessel.ControlPath; } //work out which links to display int count = this.points.Count;//save previous value int numLinks = 0; bool pathLinkExist; switch (CNCCommNetUI.CustomMode) { case CNCCommNetUI.CustomDisplayMode.None: numLinks = 0; break; case CNCCommNetUI.CustomDisplayMode.FirstHop: case CNCCommNetUI.CustomDisplayMode.Path: if (cnvessel.ControlState == VesselControlState.Probe || cnvessel.ControlState == VesselControlState.Kerbal || path.Count == 0) { numLinks = 0; } else { if (CNCCommNetUI.CustomMode == CNCCommNetUI.CustomDisplayMode.FirstHop) { path.First.GetPoints(this.points); numLinks = 1; } else { path.GetPoints(this.points, true); numLinks = path.Count; } } break; case CNCCommNetUI.CustomDisplayMode.VesselLinks: numLinks = node.Count; node.GetLinkPoints(this.points); break; case CNCCommNetUI.CustomDisplayMode.Network: if (net.Links.Count == 0) { numLinks = 0; } else { numLinks = net.Links.Count; net.GetLinkPoints(this.points); } break; case CNCCommNetUI.CustomDisplayMode.MultiPaths: if (net.Links.Count == 0) { numLinks = 0; } else { path = new CommPath(); path.Capacity = net.Links.Count; var vessels = CNCCommNetScenario.Instance.getCommNetVessels(); //TODO: replace it with CNM for (int i = 0; i < vessels.Count; i++) { vessels[i].computeUnloadedUpdate(); //network update is done only once for unloaded vessels so need to manually re-trigger every time //is vessel real/alive? if (!(vessels[i].ControlState == VesselControlState.Probe || vessels[i].ControlState == VesselControlState.Kerbal || vessels[i].ControlPath == null || vessels[i].ControlPath.Count == 0)) { //add each link in control path to overall path for (int controlpathIndex = 0; controlpathIndex < vessels[i].ControlPath.Count; controlpathIndex++) { pathLinkExist = false; for (int overallpathIndex = 0; overallpathIndex < path.Count; overallpathIndex++) //check if overall path has this link already { if (CNCCommNetwork.AreSame(path[overallpathIndex].a, vessels[i].ControlPath[controlpathIndex].a) && CNCCommNetwork.AreSame(path[overallpathIndex].b, vessels[i].ControlPath[controlpathIndex].b)) { pathLinkExist = true; break; } } if (!pathLinkExist) { path.Add(vessels[i].ControlPath[controlpathIndex]); //laziness wins //KSP techincally does not care if path is consisted of non-continuous links or not } } } } path.GetPoints(this.points, true); numLinks = path.Count; } break; }// end of switch //check if nothing to display if (numLinks == 0) { if (this.line != null) { this.line.active = false; } this.points.Clear(); return; } if (this.line != null) { this.line.active = true; } else { this.refreshLines = true; } ScaledSpace.LocalToScaledSpace(this.points); //seem very important if (this.refreshLines || MapView.Draw3DLines != this.draw3dLines || count != this.points.Count || this.line == null) { this.CreateLine(ref this.line, this.points);//seems it is multiple separate lines not single continuous line this.draw3dLines = MapView.Draw3DLines; this.refreshLines = false; } //paint the links switch (CNCCommNetUI.CustomMode) { case CNCCommNetUI.CustomDisplayMode.FirstHop: { this.line.SetColor(colorBlending(getConstellationColor(path.First.a, path.First.b), this.colorLow, Mathf.Pow((float)path.First.signalStrength, this.colorLerpPower)), 0); break; } case CNCCommNetUI.CustomDisplayMode.Path: case CNCCommNetUI.CustomDisplayMode.MultiPaths: { for (int i = numLinks - 1; i >= 0; i--) { this.line.SetColor(colorBlending(getConstellationColor(path[i].a, path[i].b), this.colorLow, Mathf.Pow((float)path[i].signalStrength, this.colorLerpPower)), i); } break; } case CNCCommNetUI.CustomDisplayMode.VesselLinks: { CommLink[] links = new CommLink[node.Count]; node.Values.CopyTo(links, 0); for (int i = 0; i < links.Length; i++) { this.line.SetColor(colorBlending(getConstellationColor(links[i].a, links[i].b), this.colorLow, Mathf.Pow((float)links[i].GetSignalStrength(links[i].a != node, links[i].b != node), this.colorLerpPower)), i); } break; } case CNCCommNetUI.CustomDisplayMode.Network: { for (int i = numLinks - 1; i >= 0; i--) { this.line.SetColor(colorBlending(getConstellationColor(net.Links[i].a, net.Links[i].b), this.colorLow, Mathf.Pow((float)net.Links[i].GetBestSignal(), this.colorLerpPower)), i); } break; } } // end of switch if (this.draw3dLines) { this.line.SetWidth(this.lineWidth3D); this.line.Draw3D(); } else { this.line.SetWidth(this.lineWidth2D); this.line.Draw(); } }
private void ParseDelegates(string methodName, MethodInfo method, CNMAttrSequence.options sequence) { CommNetwork networkInstance = commNetworks[methodTypes[method]]; #if DEBUG if (andOrList.ContainsKey(method)) { Debug.LogFormat("CommNetManager: Parsing {0} from {1} as {2} with {3}.", methodName, networkInstance.GetType().Name, sequence, andOrList[method]); } else { Debug.LogFormat("CommNetManager: Parsing {0} from {1} as {2}.", methodName, networkInstance.GetType().Name, sequence); } #endif try { switch (methodName) { case "SetNodeConnection": Sequence_SetNodeConnection.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommNode, bool>), networkInstance, method) as Func <CommNode, CommNode, bool>, andOrList[method]); break; case "Add_CommNode": Sequence_Add_CommNode.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommNode>), networkInstance, method) as Func <CommNode, CommNode>); break; case "Add_Occluder": Sequence_Add_Occluder.Add(sequence, Delegate.CreateDelegate(typeof(Func <Occluder, Occluder>), networkInstance, method) as Func <Occluder, Occluder>); break; case "Connect": Sequence_Connect.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommNode, double, CommLink>), networkInstance, method) as Func <CommNode, CommNode, double, CommLink>); break; case "CreateShortestPathTree": Sequence_CreateShortestPathTree.Add(sequence, Delegate.CreateDelegate(typeof(Action <CommNode, CommNode>), networkInstance, method) as Action <CommNode, CommNode>); break; case "Disconnect": Sequence_Disconnect.Add(sequence, Delegate.CreateDelegate(typeof(Action <CommNode, CommNode, bool>), networkInstance, method) as Action <CommNode, CommNode, bool>, andOrList[method]); break; case "FindClosestControlSource": Sequence_FindClosestControlSource.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommPath, bool>), networkInstance, method) as Func <CommNode, CommPath, bool>, andOrList[method]); break; case "FindClosestWhere": Sequence_FindClosestWhere.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommPath, Func <CommNode, CommNode, bool>, CommNode>), networkInstance, method) as Func <CommNode, CommPath, Func <CommNode, CommNode, bool>, CommNode>); break; case "FindHome": Sequence_FindHome.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommPath, bool>), networkInstance, method) as Func <CommNode, CommPath, bool>, andOrList[method]); break; case "FindPath": Sequence_FindPath.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommPath, CommNode, bool>), networkInstance, method) as Func <CommNode, CommPath, CommNode, bool>, andOrList[method]); break; case "GetLinkPoints": Sequence_GetLinkPoints.Add(sequence, Delegate.CreateDelegate(typeof(Action <List <Vector3> >), networkInstance, method) as Action <List <Vector3> >); break; case "PostUpdateNodes": Sequence_PostUpdateNodes.Add(sequence, Delegate.CreateDelegate(typeof(Action), networkInstance, method) as Action); break; case "PreUpdateNodes": Sequence_PreUpdateNodes.Add(sequence, Delegate.CreateDelegate(typeof(Action), networkInstance, method) as Action); break; case "Rebuild": Sequence_Rebuild.Add(sequence, Delegate.CreateDelegate(typeof(Action), networkInstance, method) as Action); break; case "Remove_CommNode": Sequence_Remove_CommNode.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, bool>), networkInstance, method) as Func <CommNode, bool>, andOrList[method]); break; case "Remove_Occluder": Sequence_Remove_Occluder.Add(sequence, Delegate.CreateDelegate(typeof(Func <Occluder, bool>), networkInstance, method) as Func <Occluder, bool>, andOrList[method]); break; case "TestOcclusion": Sequence_TestOcclusion.Add(sequence, Delegate.CreateDelegate(typeof(Func <Vector3d, Occluder, Vector3d, Occluder, double, bool>), networkInstance, method) as Func <Vector3d, Occluder, Vector3d, Occluder, double, bool>, andOrList[method]); break; case "TryConnect": Sequence_TryConnect.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommNode, double, bool, bool, bool, bool>), networkInstance, method) as Func <CommNode, CommNode, double, bool, bool, bool, bool>, andOrList[method]); break; case "UpdateNetwork": Sequence_UpdateNetwork.Add(sequence, Delegate.CreateDelegate(typeof(Action), networkInstance, method) as Action); break; case "UpdateShortestPath": Sequence_UpdateShortestPath.Add(sequence, Delegate.CreateDelegate(typeof(Action <CommNode, CommNode, CommLink, double, CommNode, CommNode>), networkInstance, method) as Action <CommNode, CommNode, CommLink, double, CommNode, CommNode>); break; case "UpdateShortestWhere": Sequence_UpdateShortestWhere.Add(sequence, Delegate.CreateDelegate(typeof(Func <CommNode, CommNode, CommLink, double, CommNode, Func <CommNode, CommNode, bool>, CommNode>), networkInstance, method) as Func <CommNode, CommNode, CommLink, double, CommNode, Func <CommNode, CommNode, bool>, CommNode>); break; default: #if DEBUG log.warning("The method passed (" + methodName + ") was not a standard CommNet method."); #endif return; } log.debug("Successfully parsed " + methodName + " from type " + networkInstance.GetType().Name); } catch (Exception ex) { log.error("Encountered an error creating a delegate for " + methodName + " from type " + networkInstance.GetType().Name); log.error(ex); } }
public CommNetManagerNetwork() { if (Instance != null) { log.warning("CommNetManagerNetwork.Instance was not null."); } Instance = this; commNetworks.Clear(); Sequence_SetNodeConnection.Clear(); Sequence_Add_CommNode.Clear(); Sequence_Add_Occluder.Clear(); Sequence_Connect.Clear(); Sequence_CreateShortestPathTree.Clear(); Sequence_Disconnect.Clear(); Sequence_FindClosestControlSource.Clear(); Sequence_FindClosestWhere.Clear(); Sequence_FindHome.Clear(); Sequence_FindPath.Clear(); Sequence_GetLinkPoints.Clear(); Sequence_PostUpdateNodes.Clear(); Sequence_PreUpdateNodes.Clear(); Sequence_Rebuild.Clear(); Sequence_Remove_CommNode.Clear(); Sequence_Remove_Occluder.Clear(); Sequence_TestOcclusion.Clear(); Sequence_TryConnect.Clear(); Sequence_UpdateNetwork.Clear(); Sequence_UpdateShortestPath.Clear(); Sequence_UpdateShortestWhere.Clear(); if (!methodsLoaded) { CommNetManagerNetwork.Initiate(); } log.debug(networkTypes.Count); foreach (Type type in networkTypes) { if (type == typeof(CommNetwork) || type == typeof(CommNetManagerNetwork)) { log.debug("Skipping type " + type.Name); continue; } CommNetwork typeNetworkInstance = null; try { typeNetworkInstance = Activator.CreateInstance(type) as CommNetwork; } catch (Exception ex) { log.error("Encountered an exception while calling the constructor for " + type.Name); log.error(ex); } if (typeNetworkInstance != null) { commNetworks.Add(type, typeNetworkInstance); log.info("Activated an instance of type: " + type.Name); } else { log.warning("Failed to activate " + type.Name); } } foreach (SequenceList <MethodInfo> methodList in methodsSequence.Values) { foreach (MethodInfo method in methodList.Early) { if (!commNetworks.ContainsKey(methodTypes[method])) { log.warning("No instance of the CommNetwork type (" + methodTypes[method].DeclaringType.FullName.ToString() + ") was instantiated."); continue; } ParseDelegates(method.Name, method, CNMAttrSequence.options.EARLY); } foreach (MethodInfo method in methodList.Late) { if (!commNetworks.ContainsKey(methodTypes[method])) { log.warning("No instance of the CommNetwork type (" + methodTypes[method].DeclaringType.FullName.ToString() + ") was instantiated."); continue; } ParseDelegates(method.Name, method, CNMAttrSequence.options.LATE); } foreach (MethodInfo method in methodList.Post) { if (!commNetworks.ContainsKey(methodTypes[method])) { log.warning("No instance of the CommNetwork type (" + methodTypes[method].DeclaringType.FullName.ToString() + ") was instantiated."); continue; } ParseDelegates(method.Name, method, CNMAttrSequence.options.POST); } } }
protected override void UpdateDisplay() { base.UpdateDisplay(); if (CommNetNetwork.Instance == null) { return; } if (CommNetUI.Mode == CommNetUI.DisplayMode.None) { return; } List <Vector3> targetPoints = new List <Vector3>(); List <Vector3> cone3Points = new List <Vector3>(); List <Vector3> cone10Points = new List <Vector3>(); // We COULD but do not need to rewrite how CommNetUI displays its normal link stuff. // Let's just get started by displaying antenna cones for now, for nodes the UI asks about. CommNetwork commNet = CommNetNetwork.Instance.CommNet; CommNetVessel commNetVessel = null; CommNode commNode = null; CommPath commPath = null; if (this.vessel != null && this.vessel.connection != null && this.vessel.connection.Comm.Net != null) { commNetVessel = this.vessel.connection; commNode = commNetVessel.Comm; commPath = commNetVessel.ControlPath; } // Big switch statement seeking cases of nothing to do. switch (CommNetUI.Mode) { case DisplayMode.FirstHop: GatherAntennaCones(commNode as RACommNode, ref targetPoints, ref cone3Points, ref cone10Points); break; case CommNetUI.DisplayMode.VesselLinks: GatherAntennaCones(commNode as RACommNode, ref targetPoints, ref cone3Points, ref cone10Points); break; case CommNetUI.DisplayMode.Path: foreach (CommLink link in commPath) { GatherAntennaCones(link.start as RACommNode, ref targetPoints, ref cone3Points, ref cone10Points); } break; case CommNetUI.DisplayMode.Network: for (int i = 0; i < commNet.Count; i++) { CommNode node = commNet[i]; GatherAntennaCones(node as RACommNode, ref targetPoints, ref cone3Points, ref cone10Points); } break; } ScaledSpace.LocalToScaledSpace(targetPoints); CreateLine(ref targetLine, targetPoints); targetLine.name = "RACommNetUIVectorToTarget"; targetLine.SetColor(colorToTarget); targetLine.active = drawTarget; ScaledSpace.LocalToScaledSpace(cone3Points); CreateLine(ref cone3Line, cone3Points); cone3Line.name = "RACommNetUIVectorCone3dB"; // cone3Line.material = MapView.DottedLinesMaterial; cone3Line.SetColor(color3dB); cone3Line.active = drawCone3; ScaledSpace.LocalToScaledSpace(cone10Points); CreateLine(ref cone10Line, cone10Points); cone10Line.name = "RACommNetUIVectorCone10dB"; cone10Line.SetColor(color10dB); cone10Line.active = drawCone10; float width = draw3dLines ? lineWidth3D : lineWidth2D; targetLine.SetWidth(width); cone3Line.SetWidth(width); cone10Line.SetWidth(width); //Debug.LogFormat("Drawing lines in {0} with width {1} cone3Color {2}", draw3dLines ? "3D" : "2D", width, cone3Line.GetColor(0)); if (this.draw3dLines) { // Why do these calls NOT work? Nothing renders. targetLine.Draw3D(); cone3Line.Draw3D(); cone10Line.Draw3D(); } else { targetLine.Draw(); cone3Line.Draw(); cone10Line.Draw(); } }