Exemple #1
0
        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;
            }
        }
        // constructor
        /// <summary> Creates a <see cref="ConnectionInfo"/> object for the specified vessel from it's antenna modules</summary>
        public ConnectionInfo(Vessel v, bool powered, bool storm)
        {
            // set RemoteTech powered and storm state
            if (RemoteTech.Enabled)
            {
                RemoteTech.SetPoweredDown(v.id, !powered);
                RemoteTech.SetCommsBlackout(v.id, storm);
            }

            // return no connection if there is no ec left
            if (!powered)
            {
                // hysteresis delay
                if (DB.Vessel(v).hyspos_signal >= 5.0)
                {
                    DB.Vessel(v).hyspos_signal = 5.0;
                    DB.Vessel(v).hysneg_signal = 0.0;
                    return;
                }
                DB.Vessel(v).hyspos_signal += 0.1;
            }
            else
            {
                // hysteresis delay
                DB.Vessel(v).hysneg_signal += 0.1;
                if (DB.Vessel(v).hysneg_signal < 5.0)
                {
                    return;
                }
                DB.Vessel(v).hysneg_signal = 5.0;
                DB.Vessel(v).hyspos_signal = 0.0;
            }

            // if CommNet is enabled
            if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
            {
                AntennaInfoCommNet antennaInfo = new AntennaInfoCommNet(v);

                if (v.connection != null)
                {
                    // force CommNet update of unloaded vessels
                    if (!v.loaded)
                    {
                        Lib.ReflectionValue(v.connection, "unloadedDoOnce", true);
                    }

                    // are we connected to DSN
                    if (v.connection.IsConnected)
                    {
                        ec   = antennaInfo.ec;
                        rate = antennaInfo.rate * PreferencesBasic.Instance.transmitFactor;

                        linked      = true;
                        status      = v.connection.ControlPath.First.hopType == CommNet.HopType.Home ? LinkStatus.direct_link : LinkStatus.indirect_link;
                        strength    = v.connection.SignalStrength;
                        rate       *= strength;
                        target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20);

                        if (status != 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
                            rate = Math.Min(Cache.VesselInfo(FlightGlobals.FindVessel(firstHop.id)).connection.rate, rate);
                        }
                    }
                    // is loss of connection due to plasma blackout
                    else if (Lib.ReflectionValue <bool>(v.connection, "inPlasma"))                     // calling InPlasma causes a StackOverflow :(
                    {
                        status = LinkStatus.plasma;
                    }
                }
                // if nothing has changed, no connection
                return;
            }
            // RemoteTech signal system
            else if (RemoteTech.Enabled)
            {
                AntennaInfoRT antennaInfo = new AntennaInfoRT(v);

                // are we connected
                if (RemoteTech.Connected(v.id))
                {
                    ec   = antennaInfo.ec;
                    rate = antennaInfo.rate * PreferencesBasic.Instance.transmitFactor;

                    linked      = RemoteTech.ConnectedToKSC(v.id);
                    status      = RemoteTech.TargetsKSC(v.id) ? LinkStatus.direct_link : LinkStatus.indirect_link;
                    target_name = status == LinkStatus.direct_link ? Lib.Ellipsis("DSN: " + (RemoteTech.NameTargetsKSC(v.id) ?? ""), 20) :
                                  Lib.Ellipsis(RemoteTech.NameFirstHopToKSC(v.id) ?? "", 20);

                    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));

                            // If using relay, get the lowest rate
                            if (status != LinkStatus.direct_link)
                            {
                                Vessel target = FlightGlobals.FindVessel(controlPath[0]);
                                strength *= Cache.VesselInfo(target).connection.strength;
                                rate      = Math.Min(Cache.VesselInfo(target).connection.rate, rate * strength);
                            }
                            else
                            {
                                rate *= strength;
                            }
                        }
                    }
                }
                // is loss of connection due to a blackout
                else if (RemoteTech.GetCommsBlackout(v.id))
                {
                    status = storm ? LinkStatus.storm : LinkStatus.plasma;
                }
                // if nothing has changed, no connection
                return;
            }
            // the simple stupid always connected signal system
            else
            {
                AntennaInfoCommNet antennaInfo = new AntennaInfoCommNet(v);
                ec   = antennaInfo.ec * 0.16;               // Consume 16% of the stock ec. Workaround for drain consumption with CommNet, ec consumption turns similar of RT
                rate = antennaInfo.rate * PreferencesBasic.Instance.transmitFactor;

                linked      = true;
                status      = LinkStatus.direct_link;
                strength    = 1;                 // 100 %
                target_name = "DSN: KSC";
            }
        }
Exemple #3
0
        /// <summary>
        /// Shows the Network status, ControlPath, Signal strength
        /// </summary>
        public static void ConnMan(this Panel p, Vessel v)
        {
            // avoid corner-case when this is called in a lambda after scene changes
            v = FlightGlobals.FindVessel(v.id);

            // if vessel doesn't exist anymore, leave the panel empty
            if (v == null)
            {
                return;
            }

            // get info from the cache
            Vessel_info vi = Cache.VesselInfo(v);

            // if not a valid vessel, leave the panel empty
            if (!vi.is_valid)
            {
                return;
            }

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " <color=#cccccc>CONNECTION MANAGER</color>"));
            p.Width(Styles.ScaleWidthFloat(365.0f));
            p.paneltype = Panel.PanelType.connection;

            // time-out simulation
            if (p.Timeout(vi))
            {
                return;
            }

            // draw ControlPath section
            p.AddSection("CONTROL PATH");
            if (vi.connection.linked)
            {
                if (RemoteTech.Enabled)
                {
                    if (vi.connection.controlPath != null)
                    {
                        Guid i = v.id;
                        foreach (Guid id in vi.connection.controlPath)
                        {
                            p.AddContent(
                                Lib.Ellipsis(RemoteTech.GetSatelliteName(i) + " \\ " + RemoteTech.GetSatelliteName(id), 35),
                                Lib.HumanReadablePerc(Math.Ceiling((1 - (RemoteTech.GetCommsDistance(i, id) / RemoteTech.GetCommsMaxDistance(i, id))) * 10000) / 10000, "F2"),
                                "\nDistance: " + Lib.HumanReadableRange(RemoteTech.GetCommsDistance(i, id)) +
                                "\nMax Distance: " + Lib.HumanReadableRange(RemoteTech.GetCommsMaxDistance(i, id)));
                            i = id;
                        }
                    }
                }
                if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
                {
                    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);

                        p.AddContent(
                            Lib.Ellipsis(Localizer.Format(link.end.name).Replace("Kerbin", "DSN"), 35),
                            Lib.HumanReadablePerc(Math.Ceiling(signalStrength * 10000) / 10000, "F2"),
                            "\nDistance: " + Lib.HumanReadableRange((link.start.position - link.end.position).magnitude) +
                            "\nMax Distance: " + Lib.HumanReadableRange(Math.Sqrt((link.start.antennaTransmit.power + link.start.antennaRelay.power) * link.end.antennaRelay.power))
                            );
                    }
                }
            }
            else
            {
                p.AddContent("<i>no connection</i>", string.Empty);
            }
        }