void FindAntenna()
 {
     baseAntenna  = part.GetComponent <ModuleDataTransmitterFeedeable>();
     deployModule = part.GetComponent <ModuleDeployableAntenna>();
     if (baseAntenna != null)
     {
         baseAntennaRange = baseAntenna.antennaPower;
     }
     else
     {
         RTAntennaPartModule = part.Modules.Contains("ModuleRTAntenna") ? part.Modules["ModuleRTAntenna"] : null;
         if (RTAntennaPartModule != null)
         {
             try
             {
                 FieldInfo fi = RTAntennaPartModule.GetType().GetField("Mode1DishRange");
                 baseAntennaRange = (float)(fi.GetValue(RTAntennaPartModule));
             }
             catch (Exception e)
             {
                 Debug.LogError("[NearFutureExploration] [ModuleAntennaFeed]: Mismatched RemoteTech antenna module");
             }
         }
         else
         {
             Debug.LogError("[NearFutureExploration] [ModuleAntennaFeed]: Could not find an antenna module for use as feeder");
         }
     }
     if (deployModule != null)
     {
         Debug.Log("[NearFutureExploration] [ModuleAntennaFeed]: Feed is deployable");
         deployable = true;
     }
 }
 protected override void DI_Start(StartState state)
 {
     if (HighLogic.LoadedSceneIsFlight)
     {
         this.antennaModule = this.part.Modules.OfType <ModuleDeployableAntenna>().First();
     }
 }
        public override void OnStart(StartState state)
        {
            if (state == StartState.Editor || state == StartState.None || state == StartState.PreLaunch)
            {
                return;
            }

            transmitter = part.FindModuleImplementing <ModuleDataTransmitter>();

            if (transmitter != null)
            {
                // add event to update cache when antenna be extended or retracted
                ModuleDeployableAntenna deployMod = part.FindModuleImplementing <ModuleDeployableAntenna>();
                if (deployMod != null)
                {
                    deployMod.OnStop.Add(OnAntennaDeployment);
                }

                // I hide it because it don't show the right information (should be antenna_power * rangeModifier)
                transmitter.Fields["powerText"].guiActive             = false;
                transmitter.Fields["statusText"].guiActive            = false;
                transmitter.Events["StartTransmission"].active        = false;
                transmitter.Events["TransmitIncompleteToggle"].active = false;

                // Show transmissiter rate
                if (transmitter.antennaType != AntennaType.INTERNAL)
                {
                    Rate  = Lib.HumanReadableDataRate(rate);
                    power = KSPUtil.PrintSI(transmitter.antennaPower * Antenna_Info.rangeModifier, string.Empty, 3, false);
                    Fields["Rate"].guiActive  = true;
                    Fields["power"].guiActive = true;
                }
            }
            base.OnStart(state);
        }
Exemple #4
0
 public override void OnStart(StartState state)
 {
     base.OnStart(state);
     Core.Log($"OnStart({state}) in part {part.name}");
     resourceId        = PartResourceLibrary.Instance.GetDefinition("ElectricCharge").id;
     deployableAntenna = part.FindModuleImplementing <ModuleDeployableAntenna>();
     lastUpdated       = Planetarium.GetUniversalTime();
 }
Exemple #5
0
        internal Antenna(Part part)
        {
            if (!Is(part))
            {
                throw new ArgumentException("Part is not an antenna");
            }
            Part = part;
            var internalPart = part.InternalPart;

            transmitter = internalPart.Module <ModuleDataTransmitter> ();
            deployment  = internalPart.Module <ModuleDeployableAntenna> ();
        }
 protected override void Overrides()
 {
     antenna = part.FindModuleImplementing <ModuleDataTransmitter>();
     if (antenna && antenna.CommType == 0)
     {
         Fields["displayChance"].guiActive = false;
         Fields["safetyRating"].guiActive  = false;
     }
     else
     {
         Fields["displayChance"].guiName = "Chance of Antenna Failure";
         Fields["safetyRating"].guiName  = "Antenna Safety Rating";
     }
     failureType       = "communication failure";
     deployableAntenna = part.FindModuleImplementing <ModuleDeployableAntenna>();
     remoteRepairable  = true;
 }
Exemple #7
0
        private void SetDeployableAntennaList()
        {
            deployableAntennas = new Dictionary <ModuleDeployableAntenna, bool> ();

            foreach (Part part in vessel.Parts.FindAll(
                         p => (p.Modules.Contains <ModuleDataTransmitter> ()) && (p.Modules.Contains <ModuleDeployableAntenna> ())))
            {
                bool extended = true;
                ModuleDeployableAntenna deployable = part.Modules.GetModule <ModuleDeployableAntenna> ();

                if (deployable.deployState != ModuleDeployablePart.DeployState.EXTENDED)
                {
                    extended = false;
                }
                deployableAntennas.Add(deployable, extended);
            }
        }
        /// <summary>
        /// Unhook the antenna deployment
        /// </summary>
        protected void removeListenerToAntennaDeployment(List <CNCAntennaPartInfo> antennas)
        {
            if (antennas == null)
            {
                return;
            }

            for (int i = 0; i < antennas.Count; i++)
            {
                Part thisPart = antennas[i].partReference;
                ModuleDeployableAntenna deployMod = thisPart.FindModuleImplementing <ModuleDeployableAntenna>();
                if (deployMod != null)
                {
                    deployMod.OnStop.Remove(OnAntennaDeployment);
                }
            }
        }
Exemple #9
0
        public override string GetInfo()
        {
            string text = "";

            List <ModuleDeployableAntenna> MDAs             = part.Modules.OfType <ModuleDeployableAntenna>().ToList();
            ModuleDeployableAntenna        moduleDeployable = null;

            if (MDAs.Count == 1)
            {
                moduleDeployable = MDAs[0];
            }


            bool ContainsDMSIGINT       = part.Modules.Contains("DMSIGINT");
            bool ContainsDMSoilMoisture = part.Modules.Contains("DMSoilMoisture");

            //List<ModuleDataTransmitter> MDTs = part.Modules.OfType<ModuleDataTransmitter>().ToList();
            //if (MDTs.Count == 1)
            //    moduleDT = MDTs[0];

            if (moduleDeployable == null && !ContainsDMSIGINT && !ContainsDMSoilMoisture)
            {
                text += Localizer.Format("#CAE_ConsumptionMessage");
            }
            else
            {
                text += Localizer.Format("#CAE_ConsumptionMessageExt");
            }


            if (this.resHandler.inputResources.Count == 1 &&
                this.resHandler.outputResources.Count == 0 &&
                this.resHandler.inputResources[0].name == "ElectricCharge")
            {
                double rate = this.resHandler.inputResources[0].rate;
                text += Localizer.Format("#CAE_Consumption", Formatter.StringRate(rate));
            }
            else
            {
                text += base.GetInfo();
            }

            return(text);
        }
Exemple #10
0
        void FindAntenna()
        {
            baseAntenna  = part.GetComponent <ModuleDataTransmitterFeedeable>();
            deployModule = part.GetComponent <ModuleDeployableAntenna>();
            if (baseAntenna == null)
            {
                Debug.LogError("[NearFutureExploration] [ModuleAntennaFeed]: Could not find an antenna module for use as feeder");
            }
            else
            {
                if (deployModule != null)
                {
                    Debug.Log("[NearFutureExploration] [ModuleAntennaFeed]: Feed is deployable");
                    deployable = true;
                }
            }


            baseAntennaRange = baseAntenna.antennaPower;
        }
Exemple #11
0
 public AntennaDevice(PartModule module, string ModuleName) : base(module)
 {
     this.ModuleName = ModuleName;
     if (ModuleName == "ModuleDataTransmitter")
     {
         // do we have an animation
         animDefault = module.part.FindModuleImplementing <ModuleDeployableAntenna>();
         specialCase = module.part.FindModuleImplementing <ModuleAnimateGeneric>();
         if (animDefault != null)
         {
             this.ModuleName = "ModuleDeployableAntenna";
         }
         else if (specialCase != null && !module.part.name.Contains("Lander"))
         {
             // the Mk-2 lander can has doors that can be opened via a ModuleAnimateGeneric
             // and would show up as "antenna" in automation.
             this.ModuleName = "ModuleAnimateGeneric";
         }
     }
 }
Exemple #12
0
        public override void OnStart(StartState state)
        {
            if (!Lib.IsFlight())
            {
                return;
            }

            // Kerbalism modules
            antenna    = part.FindModuleImplementing <Antenna>();
            customAnim = part.FindModuleImplementing <ModuleAnimationGroup>();
            // KSP modules
            // I'm using this.dist to save transmitter.antennaPower.
            //  CommNet - transmitter.canComm() = (isdeploy || moduleisActive)
            //    When the transmitter has no deploy(is fixed), isdeploy= True,
            //    Then the only way to disable the connection for this transmitter type is setting distance to 0 when no EC, forcing CommNet lost connection.
            //    When need enable back, take the information from this.dist
            transmitter = part.FindModuleImplementing <ModuleDataTransmitter>();
            stockAnim   = part.FindModuleImplementing <ModuleDeployableAntenna>();

            if (Features.Signal)
            {
                if (customAnim != null)
                {
                    pModule = customAnim;
                }
            }
            else if (Features.KCommNet)
            {
                if (stockAnim != null)
                {
                    pModule = stockAnim;
                }

                // Show transmissiter rate
                if (transmitter.antennaType != AntennaType.INTERNAL)
                {
                    Fields["actualECCost"].guiActive = true;
                }
            }
            base.OnStart(state);
        }
        public override void Start()
        {
            thisModule = "AntennaDeploy";
            if (Features.Signal)
            {
                antenna            = part.FindModuleImplementing <Antenna>();
                kerbalismAnimation = part.FindModuleImplementing <ModuleAnimationGroup>();
            }
            else
            {
                transmitter    = part.FindModuleImplementing <ModuleDataTransmitter>();
                StockAnimation = part.FindModuleImplementing <ModuleDeployableAntenna>();

                // I using the antennaModule & KerbalismDeploy to save distance & extend, this works for 2 purpose.
                //  First: When someone disable CommNet, Kerbalism antenna will work fine until extend is saved
                //  Second:	CommNet verify if transmitter.canComm == (isdeploy || moduleisActive)
                //    when the transmitter dosn't has deploy(is fixed), the only way to disable the connection is Setting distance to 0 when no EC, forcing CommNet lost connection.
                antenna            = part.FindModuleImplementing <Antenna>();
                kerbalismAnimation = part.FindModuleImplementing <ModuleAnimationGroup>();
            }
        }
Exemple #14
0
        public Antenna_Info(Vessel v)
        {
            List <AntennaPartInfo> adaptorsInfoList = new List <AntennaPartInfo>();

            int numParts = (!v.loaded) ? v.protoVessel.protoPartSnapshots.Count : v.Parts.Count;

            for (int partIndex = 0; partIndex < numParts; partIndex++)
            {
                Part part;
                ProtoPartSnapshot protoPart = null;

                if (v.loaded)
                {
                    part = v.Parts[partIndex];
                }
                else
                {
                    protoPart = v.protoVessel.protoPartSnapshots[partIndex];
                    part      = PartLoader.getPartInfoByName(protoPart.partName).partPrefab;
                }

                bool                    hasInfo         = false;
                AntennaPartInfo         antennaPartInfo = new AntennaPartInfo();
                ProtoPartModuleSnapshot protoPartModule = null;

                // Inspect each module of the part
                for (int moduleIndex = 0; moduleIndex < part.Modules.Count; moduleIndex++)
                {
                    NetworkAdaptor antennaMod = new NetworkAdaptor();
                    PartModule     pModule    = part.Modules[moduleIndex];
                    if (pModule is NetworkAdaptor)
                    {
                        if (v.loaded)
                        {
                            antennaMod = (NetworkAdaptor)pModule;
                            antennaPartInfo.frequency = antennaMod.frequency;
                            antennaPartInfo.ecCost    = antennaMod.ecCost;
                            antennaPartInfo.rate      = antennaMod.rate;
                            antennaPartInfo.name      = part.partInfo.title;
                        }
                        else
                        {
                            ProtoPartModuleSnapshot netAdaptor = FlightGlobals.FindProtoPartByID(protoPart.flightID).FindModule("NetworkAdaptor");
                            antennaPartInfo.frequency = Lib.Proto.GetShort(netAdaptor, "frequency");
                            antennaPartInfo.ecCost    = Lib.Proto.GetDouble(netAdaptor, "ecCost");
                            antennaPartInfo.rate      = Lib.Proto.GetDouble(netAdaptor, "rate");
                            antennaPartInfo.name      = protoPart.partInfo.title;
                        }

                        hasInfo = true;
                    }
                    else if (pModule is ICommAntenna)
                    {
                        ICommAntenna antenna = pModule as ICommAntenna;

                        // This method only works when v.Loaded, otherwise this brings a wrong deployState
                        ModuleDeployableAntenna anim = part.FindModuleImplementing <ModuleDeployableAntenna>();

                        // Assume extended if there is no animator
                        if (anim != null)
                        {
                            if (!v.loaded)
                            {
                                // This method works to !v.Loaded
                                ProtoPartModuleSnapshot deployState = FlightGlobals.FindProtoPartByID(protoPart.flightID).FindModule("ModuleDeployableAntenna");
                                antennaPartInfo.deployState = Lib.KCOMMNET.String_to_DeployState(Lib.Proto.GetString(deployState, "deployState"));
                            }
                            else
                            {
                                antennaPartInfo.deployState = anim.deployState;
                            }
                        }
                        else
                        {
                            antennaPartInfo.deployState = ModuleDeployablePart.DeployState.EXTENDED;
                        }

                        if (!v.loaded)
                        {
                            protoPartModule = protoPart.FindModule(pModule, moduleIndex);
                        }

                        antennaPartInfo.antennaPower              = (!v.loaded) ? antenna.CommPowerUnloaded(protoPartModule) : antenna.CommPower;
                        antennaPartInfo.antennaCombinable         = antenna.CommCombinable;
                        antennaPartInfo.antennaCombinableExponent = antenna.CommCombinableExponent;
                        antennaPartInfo.antennaType = antenna.CommType;
                        //antennaPartInfo.partReference = part;
                        //antennaPartInfo.partSnapshotReference = protoPart;
                        antennaPartInfo.canComm = (!v.loaded) ? antenna.CanCommUnloaded(protoPartModule) : antenna.CanComm();

                        hasInfo = true;
                    }
                }

                if (hasInfo)
                {
                    adaptorsInfoList.Add(antennaPartInfo);
                }
            }

            freqSortedList     = adaptorsInfoList.OrderBy(a => a.frequency).ToList(); // order by frequency
            adaptorsSortedList = adaptorsInfoList.OrderBy(a => a.name).ToList();      // order by device name

            AntennaCalc(freqSortedList);
        }
Exemple #15
0
        public static double GetActualVesselPower(Vessel v, bool onlyRelay = false, bool checkIfExtended = true, bool applyMod = true)
        {
            // This function should be more generic and also used in the editor
            // will see later...
            double biggest = 0;
            List <ModuleDataTransmitter> combList = new List <ModuleDataTransmitter> ();

            if (v.parts.Count > 0)
            {
                foreach (Part p in v.parts)
                {
                    if (p.Modules.Contains <ModuleDataTransmitter> ())
                    {
                        // Check extendability
                        if (checkIfExtended)
                        {
                            if (p.Modules.Contains <ModuleDeployableAntenna>())
                            {
                                ModuleDeployableAntenna antDep = p.Modules.GetModule <ModuleDeployableAntenna> ();
                                if ((antDep.deployState != ModuleDeployablePart.DeployState.EXTENDED) &&
                                    (antDep.deployState != ModuleDeployablePart.DeployState.EXTENDING))
                                {
                                    continue;
                                }
                            }
                        }

                        ModuleDataTransmitter ant = p.Modules.GetModule <ModuleDataTransmitter> ();

                        // Check if relay
                        if (onlyRelay)
                        {
                            if (ant.antennaType != AntennaType.RELAY)
                            {
                                continue;
                            }
                        }

                        // All good
                        if (ant.antennaPower > biggest)
                        {
                            biggest = ant.antennaPower;
                        }
                        if (ant.antennaCombinable)
                        {
                            combList.Add(ant);
                        }
                    }
                }
            }
            else
            {
                // This is for the tracking station, as the active vessel isn't actually active
                foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                {
                    if (p.partPrefab.Modules.Contains <ModuleDataTransmitter> ())
                    {
                        // Check extendability
                        if (checkIfExtended)
                        {
                            if (p.partPrefab.Modules.Contains <ModuleDeployableAntenna>())
                            {
                                string antDep = p.modules.Find(x => x.moduleName == "ModuleDeployableAntenna").moduleValues.GetValue("deployState");
                                if ((antDep != "EXTENDED") &&
                                    (antDep != "EXTENDING"))
                                {
                                    continue;
                                }
                            }
                        }

                        ModuleDataTransmitter ant = p.partPrefab.Modules.GetModule <ModuleDataTransmitter> ();
                        // Check if relay
                        if (onlyRelay)
                        {
                            if (ant.antennaType != AntennaType.RELAY)
                            {
                                continue;
                            }
                        }

                        // All good
                        if (ant.antennaPower > biggest)
                        {
                            biggest = ant.antennaPower;
                        }
                        if (ant.antennaCombinable)
                        {
                            combList.Add(ant);
                        }
                    }
                }
            }

            double comb;

            if (applyMod)
            {
                biggest = TruePower(biggest);
                comb    = GetVesselPower(combList);
            }
            else
            {
                comb = GetVesselPower(combList, false);
            }


            if (comb > biggest)
            {
                return(comb);
            }
            else
            {
                return(biggest);
            }
        }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            deployable = part.FindModuleImplementing <ModuleDeployableAntenna>(); // may be null
        }
        public AntennaInfoCommNet(Vessel v)
        {
            List <ModuleDataTransmitter> transmitters;

            // if vessel is loaded
            if (v.loaded)
            {
                // find transmitters
                transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();

                if (transmitters != null)
                {
                    foreach (ModuleDataTransmitter t in transmitters)
                    {
                        // Disable all stock buttons
                        t.Events["TransmitIncompleteToggle"].active = false;
                        t.Events["StartTransmission"].active        = false;
                        t.Events["StopTransmission"].active         = false;
                        t.Actions["StartTransmissionAction"].active = false;

                        Lib.Log("Data rate: " + t.name + " " + t.DataRate);

                        if (t.antennaType == AntennaType.INTERNAL)                         // do not include internal data rate, ec cost only
                        {
                            ec += t.DataResourceCost * t.DataRate;
                        }
                        else
                        {
                            // do we have an animation
                            ModuleDeployableAntenna animation        = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                            ModuleAnimateGeneric    animationGeneric = t.part.FindModuleImplementing <ModuleAnimateGeneric>();
                            if (animation != null)
                            {
                                // only include data rate and ec cost if transmitter is extended
                                if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                                {
                                    rate += t.DataRate;
                                    ec   += t.DataResourceCost * t.DataRate;
                                }
                            }
                            else if (animationGeneric != null)
                            {
                                // only include data rate and ec cost if transmitter is extended
                                if (animationGeneric.animSpeed > 0)
                                {
                                    rate += t.DataRate;
                                    ec   += t.DataResourceCost * t.DataRate;
                                }
                            }
                            // no animation
                            else
                            {
                                rate += t.DataRate;
                                ec   += t.DataResourceCost * t.DataRate;
                            }
                        }
                    }
                }
            }
            // if vessel is not loaded
            else
            {
                // find proto transmitters
                foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                {
                    // get part prefab (required for module properties)
                    Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;

                    transmitters = part_prefab.FindModulesImplementing <ModuleDataTransmitter>();

                    if (transmitters != null)
                    {
                        foreach (ModuleDataTransmitter t in transmitters)
                        {
                            if (t.antennaType == AntennaType.INTERNAL)                             // do not include internal data rate, ec cost only
                            {
                                ec += t.DataResourceCost * t.DataRate;
                            }
                            else
                            {
                                // do we have an animation
                                ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna") ?? p.FindModule("ModuleAnimateGeneric");
                                if (m != null)
                                {
                                    // only include data rate and ec cost if transmitter is extended
                                    string deployState = Lib.Proto.GetString(m, "deployState");
                                    float  animSpeed   = Lib.Proto.GetFloat(m, "animSpeed");
                                    if (deployState == "EXTENDED" || animSpeed > 0)
                                    {
                                        rate += t.DataRate;
                                        ec   += t.DataResourceCost * t.DataRate;
                                    }
                                }
                                // no animation
                                else
                                {
                                    rate += t.DataRate;
                                    ec   += t.DataResourceCost * t.DataRate;
                                }
                            }
                        }
                    }
                }
            }

            if (Settings.Science)
            {
                // Rate right now is in Mb/s, which is OP.
                // Let's assume it is in kb/s instead.
                // this is a workaround. we probably should have our own data transmitter module.
                rate /= 1024.0;
            }
        }
        // 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;
            }

            rate          = 0.0;
            internal_cost = 0.0;
            external_cost = 0.0;

            // CommNet or simple signal system
            if (!RemoteTech.Enabled)
            {
                List <ModuleDataTransmitter> transmitters;

                // if vessel is loaded
                if (v.loaded)
                {
                    // find transmitters
                    transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();

                    if (transmitters != null)
                    {
                        foreach (ModuleDataTransmitter t in transmitters)
                        {
                            if (t.antennaType == AntennaType.INTERNAL)                             // do not include internal data rate, ec cost only
                            {
                                internal_cost += t.DataResourceCost * t.DataRate;
                            }
                            else
                            {
                                // do we have an animation
                                ModuleDeployableAntenna animation        = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                                ModuleAnimateGeneric    animationGeneric = t.part.FindModuleImplementing <ModuleAnimateGeneric>();
                                if (animation != null)
                                {
                                    // only include data rate and ec cost if transmitter is extended
                                    if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                                    {
                                        rate          += t.DataRate;
                                        external_cost += t.DataResourceCost * t.DataRate;
                                    }
                                }
                                else if (animationGeneric != null)
                                {
                                    // only include data rate and ec cost if transmitter is extended
                                    if (animationGeneric.animSpeed > 0)
                                    {
                                        rate          += t.DataRate;
                                        external_cost += t.DataResourceCost * t.DataRate;
                                    }
                                }
                                // no animation
                                else
                                {
                                    rate          += t.DataRate;
                                    external_cost += t.DataResourceCost * t.DataRate;
                                }
                            }
                        }
                    }
                }

                // if vessel is not loaded
                else
                {
                    // find proto transmitters
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        // get part prefab (required for module properties)
                        Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;

                        transmitters = part_prefab.FindModulesImplementing <ModuleDataTransmitter>();

                        if (transmitters != null)
                        {
                            foreach (ModuleDataTransmitter t in transmitters)
                            {
                                if (t.antennaType == AntennaType.INTERNAL)                                 // do not include internal data rate, ec cost only
                                {
                                    internal_cost += t.DataResourceCost * t.DataRate;
                                }
                                else
                                {
                                    // do we have an animation
                                    ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna") ?? p.FindModule("ModuleAnimateGeneric");
                                    if (m != null)
                                    {
                                        // only include data rate and ec cost if transmitter is extended
                                        string deployState = Lib.Proto.GetString(m, "deployState");
                                        float  animSpeed   = Lib.Proto.GetFloat(m, "animSpeed");
                                        if (deployState == "EXTENDED" || animSpeed > 0)
                                        {
                                            rate          += t.DataRate;
                                            external_cost += t.DataResourceCost * t.DataRate;
                                        }
                                    }
                                    // no animation
                                    else
                                    {
                                        rate          += t.DataRate;
                                        external_cost += t.DataResourceCost * t.DataRate;
                                    }
                                }
                            }
                        }
                    }
                }

                // if CommNet is enabled
                if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
                {
                    if (v.connection != null)
                    {
                        // force CommNet update of unloaded vessels
                        if (!v.loaded)
                        {
                            Lib.ReflectionValue(v.connection, "unloadedDoOnce", true);
                        }

                        // are we connected to DSN or control station(can be another vessel with 3 or more crew in CommNet)
                        if (v.connection.IsConnected)
                        {
                            linked   = true;
                            status   = v.connection.ControlPath.First.hopType == HopType.Home ? LinkStatus.direct_link : LinkStatus.indirect_link;
                            strength = v.connection.SignalStrength;

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

                            rate       *= strength * PreferencesBasic.Instance.transmitFactor;
                            target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20);
                        }

                        // is loss of connection due to plasma blackout
                        else if (Lib.ReflectionValue <bool>(v.connection, "inPlasma"))                         // calling InPlasma causes a StackOverflow :(
                        {
                            status        = LinkStatus.plasma;
                            rate          = 0.0;
                            internal_cost = 0.0;
                            external_cost = 0.0;
                        }
                    }
                    // no connection
                    else
                    {
                        rate          = 0.0;
                        internal_cost = 0.0;
                        external_cost = 0.0;
                    }
                    return;
                }
                // the simple stupid always connected signal system
                linked      = true;
                status      = LinkStatus.direct_link;
                strength    = 1;                 // 100 %
                target_name = "DSN: KSC";
                return;
            }

            // RemoteTech signal system
            else
            {
                // if vessel is loaded
                if (v.loaded)
                {
                    // find transmitters
                    foreach (Part p in v.parts)
                    {
                        foreach (PartModule m in p.Modules)
                        {
                            // calculate internal (passive) transmitter ec usage @ 0.5W each
                            if (m.moduleName == "ModuleRTAntennaPassive")
                            {
                                internal_cost += 0.0005;
                            }

                            // calculate external transmitters
                            else if (m.moduleName == "ModuleRTAntenna")
                            {
                                // only include ec cost if transmitter is active
                                if (Lib.ReflectionValue <bool>(m, "IsRTActive"))
                                {
                                    rate          += Lib.ReflectionValue <float>(m, "RTPacketSize") / Lib.ReflectionValue <float>(m, "RTPacketInterval");
                                    external_cost += m.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate;
                                }
                            }
                        }
                    }
                }

                // if vessel is not loaded
                else
                {
                    // find proto transmitters
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        // get part prefab (required for module properties)
                        Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;
                        int  index       = 0;                       // module index

                        foreach (ProtoPartModuleSnapshot m in p.modules)
                        {
                            // calculate internal (passive) transmitter ec usage @ 0.5W each
                            if (m.moduleName == "ModuleRTAntennaPassive")
                            {
                                internal_cost += 0.0005;
                            }

                            // calculate external transmitters
                            else if (m.moduleName == "ModuleRTAntenna")
                            {
                                // only include data rate and ec cost if transmitter is active skip if index is out of range
                                if (Lib.Proto.GetBool(m, "IsRTActive") && index < part_prefab.Modules.Count)
                                {
                                    // get module prefab
                                    PartModule pm = part_prefab.Modules.GetModule(index);

                                    if (pm != null)
                                    {
                                        external_cost += pm.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate;
                                        // only include data rate if vessel is connected
                                        float?packet_size = Lib.SafeReflectionValue <float>(pm, "RTPacketSize");
                                        // workaround for old savegames
                                        if (packet_size == null)
                                        {
                                            Lib.Debug("Old SaveGame PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround", p.partName, v.vesselName);
                                            rate += 6.6666;                                              // 6.67 Mb/s
                                        }
                                        else
                                        {
                                            rate += (float)packet_size / Lib.ReflectionValue <float>(pm, "RTPacketInterval");
                                        }
                                    }
                                    else
                                    {
                                        Lib.Debug("Could not find PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround", p.partName, v.vesselName);
                                        rate          += 6.6666;                                         // 6.67 Mb/s in 100% factor
                                        external_cost += 0.025;                                          // 25 W/s
                                    }
                                }
                            }
                            index++;
                        }
                    }
                }

                // are we connected
                if (RemoteTech.Connected(v.id))
                {
                    linked      = RemoteTech.ConnectedToKSC(v.id);
                    status      = RemoteTech.TargetsKSC(v.id) ? LinkStatus.direct_link : LinkStatus.indirect_link;
                    strength    = RemoteTech.GetSignalDelay(v.id);
                    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 smaller rate of the path
                    if (controlPath != null)
                    {
                        // Get rate from the firstHop, each Hop will do the same logic, then we will have the min rate for whole path
                        if (controlPath.Length > 0)
                        {
                            rate = Math.Min(Cache.VesselInfo(FlightGlobals.FindVessel(controlPath[0])).connection.rate, rate);
                        }
                    }
                    rate *= PreferencesBasic.Instance.transmitFactor;
                }
                // is loss of connection due to a blackout
                else if (RemoteTech.GetCommsBlackout(v.id))
                {
                    status        = storm ? LinkStatus.storm : LinkStatus.plasma;
                    rate          = 0.0;
                    internal_cost = 0.0;
                    external_cost = 0.0;
                }
                else
                {
                    // no connection
                    rate          = 0.0;
                    internal_cost = 0.0;
                    external_cost = 0.0;
                }
            }
        }
Exemple #19
0
        public virtual AntennaInfo AntennaInfo()
        {
            int transmitterCount = 0;

            antennaInfo.rate = 1;
            double ec_transmitter = 0;

            // if vessel is loaded
            if (v.loaded)
            {
                List <ModuleDataTransmitter> transmitters = GetTransmittersLoaded(v);

                foreach (ModuleDataTransmitter t in transmitters)
                {
                    // Disable all stock buttons
                    t.Events["TransmitIncompleteToggle"].active = false;
                    t.Events["StartTransmission"].active        = false;
                    t.Events["StopTransmission"].active         = false;
                    t.Actions["StartTransmissionAction"].active = false;

                    // ignore broken / disabled transmitters
                    if (!t.isEnabled)
                    {
                        continue;
                    }

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        antennaInfo.ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ModuleDeployableAntenna animation        = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                        ModuleAnimateGeneric    animationGeneric = t.part.FindModuleImplementing <ModuleAnimateGeneric>();
                        if (animation != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                            {
                                antennaInfo.rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        else if (animationGeneric != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animationGeneric.animSpeed > 0)
                            {
                                antennaInfo.rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        // no animation
                        else
                        {
                            antennaInfo.rate *= t.DataRate;
                            transmitterCount++;
                            var e = t.DataResourceCost * t.DataRate;
                            ec_transmitter += e;
                        }
                    }
                }
            }
            // if vessel is not loaded
            else
            {
                List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > transmitters = GetTransmittersUnloaded(v);

                foreach (var pair in transmitters)
                {
                    ModuleDataTransmitter t = pair.Key;
                    ProtoPartSnapshot     p = pair.Value;

                    // ignore broken/disabled transmitters
                    var mdt = p.FindModule("ModuleDataTransmitter");
                    if (mdt != null && !Lib.Proto.GetBool(mdt, "isEnabled", true))
                    {
                        continue;
                    }

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        antennaInfo.ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna") ?? p.FindModule("ModuleAnimateGeneric");
                        if (m != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            string deployState = Lib.Proto.GetString(m, "deployState");
                            float  animSpeed   = Lib.Proto.GetFloat(m, "animSpeed");
                            if (deployState == "EXTENDED" || animSpeed > 0)
                            {
                                antennaInfo.rate *= t.DataRate;
                                transmitterCount++;
                                ec_transmitter += t.DataResourceCost * t.DataRate;
                            }
                        }
                        // no animation
                        else
                        {
                            antennaInfo.rate *= t.DataRate;
                            transmitterCount++;
                            ec_transmitter += t.DataResourceCost * t.DataRate;
                        }
                    }
                }
            }

            if (transmitterCount > 1)
            {
                antennaInfo.rate = Math.Pow(antennaInfo.rate, 1.0 / transmitterCount);
            }

            else if (transmitterCount == 0)
            {
                antennaInfo.rate = 0;
            }

            // when transmitting, transmitters need more EC for the signal amplifiers.
            // while not transmitting, transmitters only use 10-20% of that
            ec_transmitter *= antennaInfo.transmitting ? Settings.TransmitterActiveEcFactor : Settings.TransmitterPassiveEcFactor;

            antennaInfo.ec      = ec_transmitter * Settings.TransmitterActiveEcFactor;
            antennaInfo.ec_idle = ec_transmitter * Settings.TransmitterPassiveEcFactor;

            Init();

            if (antennaInfo.linked && transmitterCount > 0)
            {
                var bitsPerMB = 1024.0 * 1024.0 * 8.0;
                antennaInfo.rate += Settings.DataRateMinimumBitsPerSecond / bitsPerMB;
            }

            return(antennaInfo);
        }
Exemple #20
0
        public AntennaInfoCommNet(Vessel v, bool powered, bool storm, bool transmitting)
        {
            int transmitterCount = 0;

            rate = 1;
            double ec_transmitter = 0;

            // if vessel is loaded
            if (v.loaded)
            {
                List <ModuleDataTransmitter> transmitters;

                if (!Cache.HasVesselObjectsCache(v, "commnet"))
                {
                    // find transmitters
                    transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();
                    if (transmitters == null)
                    {
                        transmitters = new List <ModuleDataTransmitter>();
                    }
                    Cache.SetVesselObjectsCache(v, "commnet", transmitters);
                }
                else
                {
                    transmitters = Cache.VesselObjectsCache <List <ModuleDataTransmitter> >(v, "commnet");
                }

                foreach (ModuleDataTransmitter t in transmitters)
                {
                    // Disable all stock buttons
                    t.Events["TransmitIncompleteToggle"].active = false;
                    t.Events["StartTransmission"].active        = false;
                    t.Events["StopTransmission"].active         = false;
                    t.Actions["StartTransmissionAction"].active = false;

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ModuleDeployableAntenna animation        = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                        ModuleAnimateGeneric    animationGeneric = t.part.FindModuleImplementing <ModuleAnimateGeneric>();
                        if (animation != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        else if (animationGeneric != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            if (animationGeneric.animSpeed > 0)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                var e = t.DataResourceCost * t.DataRate;
                                ec_transmitter += e;
                            }
                        }
                        // no animation
                        else
                        {
                            rate *= t.DataRate;
                            transmitterCount++;
                            var e = t.DataResourceCost * t.DataRate;
                            ec_transmitter += e;
                        }
                    }
                }
            }
            // if vessel is not loaded
            else
            {
                List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > transmitters;
                if (!Cache.HasVesselObjectsCache(v, "commnet_bg"))
                {
                    transmitters = new List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> >();
                    // find proto transmitters
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        // get part prefab (required for module properties)
                        Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;

                        foreach (ModuleDataTransmitter t in part_prefab.FindModulesImplementing <ModuleDataTransmitter>())
                        {
                            transmitters.Add(new KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot>(t, p));
                        }
                    }

                    Cache.SetVesselObjectsCache(v, "commnet_bg", transmitters);
                }
                else
                {
                    // cache transmitters
                    transmitters = Cache.VesselObjectsCache <List <KeyValuePair <ModuleDataTransmitter, ProtoPartSnapshot> > >(v, "commnet_bg");
                }

                foreach (var pair in transmitters)
                {
                    ModuleDataTransmitter t = pair.Key;
                    ProtoPartSnapshot     p = pair.Value;

                    if (t.antennaType == AntennaType.INTERNAL)                     // do not include internal data rate, ec cost only
                    {
                        ec += t.DataResourceCost * t.DataRate;
                    }
                    else
                    {
                        // do we have an animation
                        ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna") ?? p.FindModule("ModuleAnimateGeneric");
                        if (m != null)
                        {
                            // only include data rate and ec cost if transmitter is extended
                            string deployState = Lib.Proto.GetString(m, "deployState");
                            float  animSpeed   = Lib.Proto.GetFloat(m, "animSpeed");
                            if (deployState == "EXTENDED" || animSpeed > 0)
                            {
                                rate *= t.DataRate;
                                transmitterCount++;
                                ec_transmitter += t.DataResourceCost * t.DataRate;
                            }
                        }
                        // no animation
                        else
                        {
                            rate *= t.DataRate;
                            transmitterCount++;
                            ec_transmitter += t.DataResourceCost * t.DataRate;
                        }
                    }
                }
            }

            if (transmitterCount > 1)
            {
                rate = Math.Pow(rate, 1.0 / transmitterCount);
            }
            else if (transmitterCount == 0)
            {
                rate = 0;
            }

            // when transmitting, transmitters need more EC for the signal amplifiers.
            // while not transmitting, transmitters only use 10-20% of that
            ec_transmitter *= transmitting ? Settings.TransmitterActiveEcFactor : Settings.TransmitterPassiveEcFactor;

            ec += ec_transmitter;

            Init(v, powered, storm);
        }
Exemple #21
0
        // 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;
            }

            // CommNet or simple signal system
            if (!RemoteTech.Enabled)
            {
                List <ModuleDataTransmitter> transmitters;

                // if vessel is loaded
                if (v.loaded)
                {
                    // find transmitters
                    transmitters = v.FindPartModulesImplementing <ModuleDataTransmitter>();

                    if (transmitters != null)
                    {
                        foreach (ModuleDataTransmitter t in transmitters)
                        {
                            if (t.antennaType == AntennaType.INTERNAL)                             // do not include internal data rate, ec cost only
                            {
                                internal_cost += t.DataResourceCost * t.DataRate;
                            }
                            else
                            {
                                // do we have an animation
                                ModuleDeployableAntenna animation = t.part.FindModuleImplementing <ModuleDeployableAntenna>();
                                if (animation != null)
                                {
                                    // only include data rate and ec cost if transmitter is extended
                                    if (animation.deployState == ModuleDeployablePart.DeployState.EXTENDED)
                                    {
                                        rate          += t.DataRate;
                                        external_cost += t.DataResourceCost * t.DataRate;
                                    }
                                }
                                // no animation
                                else
                                {
                                    rate          += t.DataRate;
                                    external_cost += t.DataResourceCost * t.DataRate;
                                }
                            }
                        }
                    }
                }

                // if vessel is not loaded
                else
                {
                    // find proto transmitters
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        // get part prefab (required for module properties)
                        Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;

                        transmitters = part_prefab.FindModulesImplementing <ModuleDataTransmitter>();

                        if (transmitters != null)
                        {
                            foreach (ModuleDataTransmitter t in transmitters)
                            {
                                if (t.antennaType == AntennaType.INTERNAL)                                 // do not include internal data rate, ec cost only
                                {
                                    internal_cost += t.DataResourceCost * t.DataRate;
                                }
                                else
                                {
                                    // do we have an animation
                                    ProtoPartModuleSnapshot m = p.FindModule("ModuleDeployableAntenna");
                                    if (m != null)
                                    {
                                        // only include data rate and ec cost if transmitter is extended
                                        string deployState = Lib.Proto.GetString(m, "deployState");
                                        if (deployState == "EXTENDED")
                                        {
                                            rate          += t.DataRate;
                                            external_cost += t.DataResourceCost * t.DataRate;
                                        }
                                    }
                                    // no animation
                                    else
                                    {
                                        rate          += t.DataRate;
                                        external_cost += t.DataResourceCost * t.DataRate;
                                    }
                                }
                            }
                        }
                    }
                }

                // if CommNet is enabled
                if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
                {
                    // are we connected to DSN
                    if (v.connection != null)
                    {
                        if (v.connection.IsConnected)
                        {
                            linked      = true;
                            status      = v.connection.ControlPath.First.hopType == CommNet.HopType.Home ? LinkStatus.direct_link : LinkStatus.indirect_link;
                            strength    = v.connection.SignalStrength;
                            rate        = rate * strength;
                            target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20);
                            return;
                        }

                        // is loss of connection due to plasma blackout
                        else if (Lib.ReflectionValue <bool>(v.connection, "inPlasma"))                         // calling InPlasma causes a StackOverflow :(
                        {
                            status        = LinkStatus.plasma;
                            rate          = 0.0;
                            internal_cost = 0.0;
                            external_cost = 0.0;
                            return;
                        }
                    }

                    // no connection
                    rate          = 0.0;
                    internal_cost = 0.0;
                    external_cost = 0.0;
                    return;
                }

                // the simple stupid always connected signal system
                linked      = true;
                status      = LinkStatus.direct_link;
                strength    = 1;                 // 100 %
                target_name = "DSN: KSC";
                return;
            }

            // RemoteTech signal system
            else
            {
                // if vessel is loaded
                if (v.loaded)
                {
                    // find transmitters
                    foreach (Part p in v.parts)
                    {
                        foreach (PartModule m in p.Modules)
                        {
                            // calculate internal (passive) transmitter ec usage @ 0.5W each
                            if (m.moduleName == "ModuleRTAntennaPassive")
                            {
                                internal_cost += 0.0005;
                            }

                            // calculate external transmitters
                            else if (m.moduleName == "ModuleRTAntenna")
                            {
                                // only include data rate and ec cost if transmitter is active
                                if (Lib.ReflectionValue <bool>(m, "IsRTActive"))
                                {
                                    rate          += (Lib.ReflectionValue <float>(m, "RTPacketSize") / Lib.ReflectionValue <float>(m, "RTPacketInterval"));
                                    external_cost += m.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate;
                                }
                            }
                        }
                    }
                }

                // if vessel is not loaded
                else
                {
                    // find proto transmitters
                    foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                    {
                        // get part prefab (required for module properties)
                        Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab;
                        int  index       = 0;                           // module index

                        foreach (ProtoPartModuleSnapshot m in p.modules)
                        {
                            // calculate internal (passive) transmitter ec usage @ 0.5W each
                            if (m.moduleName == "ModuleRTAntennaPassive")
                            {
                                internal_cost += 0.0005;
                            }

                            // calculate external transmitters
                            else if (m.moduleName == "ModuleRTAntenna")
                            {
                                // only include data rate and ec cost if transmitter is active skip if index is out of range
                                if (Lib.Proto.GetBool(m, "IsRTActive") && index < part_prefab.Modules.Count)
                                {
                                    // get module prefab
                                    PartModule pm = part_prefab.Modules.GetModule(index);

                                    if (pm != null)
                                    {
                                        rate          += (Lib.ReflectionValue <float>(pm, "RTPacketSize") / Lib.ReflectionValue <float>(pm, "RTPacketInterval"));
                                        external_cost += pm.resHandler.inputResources.Find(r => r.name == "ElectricCharge").rate;
                                    }
                                    else
                                    {
                                        Lib.DebugLog(String.Format("ConnectionInfo: Could not find PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround",
                                                                   p.partName, v.vesselName));
                                        rate          += 6.6666;                                            // 6.67 Mb/s
                                        external_cost += 0.025;                                             // 25 W/s
                                    }
                                }
                            }
                            index++;
                        }
                    }
                }

                // are we connected
                if (RemoteTech.Connected(v.id))
                {
                    linked      = RemoteTech.ConnectedToKSC(v.id);
                    status      = RemoteTech.TargetsKSC(v.id) ? LinkStatus.direct_link : LinkStatus.indirect_link;
                    strength    = RemoteTech.GetSignalDelay(v.id);
                    target_name = status == LinkStatus.direct_link ? Lib.Ellipsis("DSN: " + (RemoteTech.NameTargetsKSC(v.id) ?? ""), 20):
                                  Lib.Ellipsis(RemoteTech.NameFirstHopToKSC(v.id) ?? "", 20);
                    return;
                }

                // is loss of connection due to a blackout
                else if (RemoteTech.GetCommsBlackout(v.id))
                {
                    status        = storm ? LinkStatus.storm : LinkStatus.plasma;
                    rate          = 0.0;
                    internal_cost = 0.0;
                    external_cost = 0.0;
                    return;
                }

                // no connection
                rate          = 0.0;
                internal_cost = 0.0;
                external_cost = 0.0;
                return;
            }
        }