protected virtual void Init() { if (!antennaInfo.powered || v.connection == null) { antennaInfo.linked = false; antennaInfo.status = (int)LinkStatus.no_link; return; } // force CommNet update of unloaded vessels if (!v.loaded) { Lib.ReflectionValue(v.connection, "unloadedDoOnce", true); } // are we connected to DSN if (v.connection.IsConnected) { antennaInfo.linked = true; var link = v.connection.ControlPath.First; antennaInfo.status = link.hopType == CommNet.HopType.Home ? (int)LinkStatus.direct_link : (int)LinkStatus.indirect_link; antennaInfo.strength = link.signalStrength; antennaInfo.rate *= Math.Pow(link.signalStrength, Settings.DataRateDampingExponent); antennaInfo.target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20); if (antennaInfo.status != (int)LinkStatus.direct_link) { Vessel firstHop = Lib.CommNodeToVessel(v.Connection.ControlPath.First.end); // Get rate from the firstHop, each Hop will do the same logic, then we will have the min rate for whole path antennaInfo.rate = Math.Min(firstHop.KerbalismData().Connection.rate, antennaInfo.rate); } } // is loss of connection due to plasma blackout else if (Lib.ReflectionValue <bool>(v.connection, "inPlasma")) // calling InPlasma causes a StackOverflow :( { antennaInfo.status = (int)LinkStatus.plasma; } antennaInfo.control_path = new List <string[]>(); foreach (CommLink link in v.connection.ControlPath) { double antennaPower = link.end.isHome ? link.start.antennaTransmit.power + link.start.antennaRelay.power : link.start.antennaTransmit.power; double signalStrength = 1 - ((link.start.position - link.end.position).magnitude / Math.Sqrt(antennaPower * link.end.antennaRelay.power)); signalStrength = (3 - (2 * signalStrength)) * Math.Pow(signalStrength, 2); string name = Localizer.Format(link.end.displayName); if (link.end.isHome) { name = name.Replace("Kerbin", "DSN"); } name = Lib.Ellipsis(name, 35); string value = Lib.HumanReadablePerc(Math.Ceiling(signalStrength * 10000) / 10000, "F2"); string tooltip = "Distance: " + Lib.HumanReadableDistance((link.start.position - link.end.position).magnitude) + "\nMax Distance: " + Lib.HumanReadableDistance(Math.Sqrt((link.start.antennaTransmit.power + link.start.antennaRelay.power) * link.end.antennaRelay.power)); antennaInfo.control_path.Add(new string[] { name, value, tooltip }); } }
private void Init(Vessel v, bool powered, bool storm) { // are we connected if (RemoteTech.Connected(v.id)) { linked = RemoteTech.ConnectedToKSC(v.id); status = RemoteTech.TargetsKSC(v.id) ? (int)LinkStatus.direct_link : (int)LinkStatus.indirect_link; target_name = status == (int)LinkStatus.direct_link ? Lib.Ellipsis("DSN: " + (RemoteTech.NameTargetsKSC(v.id) ?? ""), 20) : Lib.Ellipsis(RemoteTech.NameFirstHopToKSC(v.id) ?? "", 20); Guid[] controlPath = null; if (linked) { controlPath = RemoteTech.GetCommsControlPath(v.id); } // Get the lowest rate in ControlPath if (controlPath != null) { // Get rate from the firstHop, each Hop will do the same logic, then we will have the lowest rate for the path if (controlPath.Length > 0) { double dist = RemoteTech.GetCommsDistance(v.id, controlPath[0]); strength = 1 - (dist / Math.Max(RemoteTech.GetCommsMaxDistance(v.id, controlPath[0]), 1)); strength = Math.Pow(strength, Settings.DataRateDampingExponentRT); // If using relay, get the lowest rate if (status != (int)LinkStatus.direct_link) { Vessel target = FlightGlobals.FindVessel(controlPath[0]); ConnectionInfo ci = target.KerbalismData().Connection; strength *= ci.strength; rate = Math.Min(ci.rate, rate * strength); } else { rate *= strength; } } control_path = new List <string[]>(); Guid i = v.id; foreach (Guid id in controlPath) { var name = Lib.Ellipsis(RemoteTech.GetSatelliteName(i) + " \\ " + RemoteTech.GetSatelliteName(id), 35); var value = Lib.HumanReadablePerc(Math.Ceiling((1 - (RemoteTech.GetCommsDistance(i, id) / RemoteTech.GetCommsMaxDistance(i, id))) * 10000) / 10000, "F2"); var tooltip = "Distance: " + Lib.HumanReadableDistance(RemoteTech.GetCommsDistance(i, id)) + "\nMax Distance: " + Lib.HumanReadableDistance(RemoteTech.GetCommsMaxDistance(i, id)); control_path.Add(new string[] { name, value, tooltip }); i = id; } } } // is loss of connection due to a blackout else if (RemoteTech.GetCommsBlackout(v.id)) { status = storm ? (int)LinkStatus.storm : (int)LinkStatus.plasma; } }
static bool Prefix(ModuleDataTransmitter __instance, ref string __result) { // Patch only if science is enabled if (!Features.Science) { return(true); } string text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(__instance.antennaType.displayDescription()); // Antenna type: direct string result = Localizer.Format("#autoLOC_7001005", text); // Antenna rating: 500km result += Localizer.Format("#autoLOC_7001006", Lib.HumanReadableDistance(__instance.antennaPower)); result += "\n"; var dsn1 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(0f)); var dsn2 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(0.5f)); var dsn3 = CommNet.CommNetScenario.RangeModel.GetMaximumRange(__instance.antennaPower, GameVariables.Instance.GetDSNRange(1f)); result += Lib.BuildString(Localizer.Format("#autoLOC_236834"), " ", Lib.HumanReadableDistance(dsn1)); result += Lib.BuildString(Localizer.Format("#autoLOC_236835"), " ", Lib.HumanReadableDistance(dsn2)); result += Lib.BuildString(Localizer.Format("#autoLOC_236836"), " ", Lib.HumanReadableDistance(dsn3)); double ec = __instance.DataResourceCost * __instance.DataRate; Specifics specs = new Specifics(); specs.Add(Local.DataTransmitter_ECidle, Lib.Color(Lib.HumanReadableRate(ec * Settings.TransmitterPassiveEcFactor), Lib.Kolor.Orange)); //"EC (idle)" if (__instance.antennaType != AntennaType.INTERNAL) { specs.Add(Local.DataTransmitter_ECTX, Lib.Color(Lib.HumanReadableRate(ec * Settings.TransmitterActiveEcFactor), Lib.Kolor.Orange)); //"EC (transmitting)" specs.Add(""); specs.Add(Local.DataTransmitter_Maxspeed, Lib.HumanReadableDataRate(__instance.DataRate)); //"Max. speed" } __result = Lib.BuildString(result, "\n\n", specs.Info()); // don't call default implementation return(false); }
public static string ReqValueFormat(Require req, object reqValue) { switch (req) { case Require.OrbitMinEccentricity: case Require.OrbitMaxEccentricity: case Require.OrbitMinArgOfPeriapsis: case Require.OrbitMaxArgOfPeriapsis: case Require.AtmosphereAltMin: case Require.AtmosphereAltMax: return(((double)reqValue).ToString("F2")); case Require.SunAngleMin: case Require.SunAngleMax: case Require.OrbitMinInclination: case Require.OrbitMaxInclination: return(Lib.HumanReadableAngle((double)reqValue)); case Require.TemperatureMin: case Require.TemperatureMax: return(Lib.HumanReadableTemp((double)reqValue)); case Require.AltitudeMin: case Require.AltitudeMax: case Require.AltAboveGroundMin: case Require.AltAboveGroundMax: case Require.MaxAsteroidDistance: return(Lib.HumanReadableDistance((double)reqValue)); case Require.RadiationMin: case Require.RadiationMax: return(Lib.HumanReadableRadiation((double)reqValue)); case Require.VolumePerCrewMin: case Require.VolumePerCrewMax: return(Lib.HumanReadableVolume((double)reqValue)); case Require.SurfaceSpeedMin: case Require.SurfaceSpeedMax: case Require.VerticalSpeedMin: case Require.VerticalSpeedMax: case Require.SpeedMin: case Require.SpeedMax: return(Lib.HumanReadableSpeed((double)reqValue)); case Require.DynamicPressureMin: case Require.DynamicPressureMax: case Require.StaticPressureMin: case Require.StaticPressureMax: case Require.AtmDensityMin: case Require.AtmDensityMax: return(Lib.HumanReadablePressure((double)reqValue)); case Require.CrewMin: case Require.CrewMax: case Require.CrewCapacityMin: case Require.CrewCapacityMax: case Require.AstronautComplexLevelMin: case Require.AstronautComplexLevelMax: case Require.TrackingStationLevelMin: case Require.TrackingStationLevelMax: case Require.MissionControlLevelMin: case Require.MissionControlLevelMax: case Require.AdministrationLevelMin: case Require.AdministrationLevelMax: return(((int)reqValue).ToString()); case Require.Module: return(KSPUtil.PrintModuleName((string)reqValue)); case Require.Part: return(PartLoader.getPartInfoByName((string)reqValue)?.title ?? (string)reqValue); default: return(string.Empty); } }