Ejemplo n.º 1
0
        static ConnectionInfo OtherComms(Vessel v, KAntennaInfo antenna, HashSet <Guid> avoid_inf_recursion)
        {
            // hard-coded transmission rate and cost
            const double ext_rate = 0.064;
            const double ext_cost = 0.1;

            // if RemoteTech is present and enabled
            if (RemoteTech.Enabled())
            {
                return(RemoteTech.Connected(v.id)
        ? new ConnectionInfo(LinkStatus.direct_link, ext_rate, ext_cost)
        : new ConnectionInfo(LinkStatus.no_link));
            }
            // if CommNet is enabled
            else if (Features.KCommNet)
            {
                return(v.connection != null && v.connection.IsConnected
        ? new ConnectionInfo(LinkStatus.direct_link, ext_rate * v.connection.SignalStrength, ext_cost)
        : new ConnectionInfo(LinkStatus.no_link));
            }
            // the simple stupid signal system
            else
            {
                return(new ConnectionInfo(LinkStatus.direct_link, ext_rate, ext_cost));
            }
        }
Ejemplo n.º 2
0
        public static ConnectionInfo connection(Vessel v)
        {
            // hard-coded transmission rate and cost
            const double ext_rate = 0.064;
            const double ext_cost = 0.1;

            // if RemoteTech is present and enabled
            if (RemoteTech.Enabled())
            {
                if (RemoteTech.Connected(v.id) && !RemoteTech.ConnectedToKSC(v.id))
                {
                    return(new ConnectionInfo(LinkStatus.indirect_link, ext_rate, ext_cost));
                }
                else if (RemoteTech.ConnectedToKSC(v.id))
                {
                    return(new ConnectionInfo(LinkStatus.direct_link, ext_rate, ext_cost));
                }
                else
                {
                    return(new ConnectionInfo(LinkStatus.no_link));
                }
            }
            // if CommNet is enabled
            else if (HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
            {
                return(v.connection != null && v.connection.IsConnected
                                  ? new ConnectionInfo(LinkStatus.direct_link, ext_rate * v.connection.SignalStrength, ext_cost)
                                  : new ConnectionInfo(LinkStatus.no_link));
            }
            // the simple stupid signal system
            else
            {
                return(new ConnectionInfo(LinkStatus.direct_link, ext_rate, ext_cost));
            }
        }
Ejemplo n.º 3
0
        public IEnumerator NetworkInitialized()
        {
            yield return(new WaitForSeconds(2));

            Communications.NetworkInitialized = true;
            RemoteTech.Startup();
        }
Ejemplo n.º 4
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;
            }
        }
Ejemplo n.º 5
0
 // return true if the vessel is subject to a signal blackout
 public static bool Blackout(Vessel v)
 {
     if (!RemoteTech.Enabled())
     {
         return(false);
     }
     return(Cache.VesselInfo(v).blackout);
 }
Ejemplo n.º 6
0
		bool render_vessel(Panel p, Vessel v)
		{
			// get vessel info
			vessel_info vi = Cache.VesselInfo(v);

			// skip invalid vessels
			if (!vi.is_valid) return false;

			// get data from db
			VesselData vd = DB.Vessel(v);

			// determine if filter must be shown
			show_filter |= vd.group.Length > 0 && vd.group != "NONE";

			// skip filtered vessels
			if (filtered() && vd.group != filter) return false;

			// get resource handler
			vessel_resources resources = ResourceCache.Get(v);

			// get vessel crew
			List<ProtoCrewMember> crew = Lib.CrewList(v);

			// get vessel name
			string vessel_name = v.isEVA ? crew[0].name : v.vesselName;

			// get body name
			string body_name = v.mainBody.name.ToUpper();

			// render entry
			p.header
			(
			  Lib.BuildString("<b>",
			  Lib.Ellipsis(vessel_name, Styles.ScaleStringLength(((page == MonitorPage.data || page == MonitorPage.log || selected_id == Guid.Empty) && !Lib.IsFlight()) ? 50 : 30)),
			  "</b> <size=", Styles.ScaleInteger(9).ToString(),
			  "><color=#cccccc>", Lib.Ellipsis(body_name, Styles.ScaleStringLength(8)), "</color></size>"),
			  string.Empty,
			  () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; }
			);

			// problem indicator
			indicator_problems(p, v, vi, crew);

			// battery indicator
			indicator_ec(p, v, vi);

			// supply indicator
			if (Features.Supplies) indicator_supplies(p, v, vi);

			// reliability indicator
			if (Features.Reliability) indicator_reliability(p, v, vi);

			// signal indicator
			if (RemoteTech.Enabled() || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet) indicator_signal(p, v, vi);

			// done
			return true;
		}
Ejemplo n.º 7
0
 public static void RTFailureHandler(Part part, string type, bool failure)
 {
     foreach (PartModule m in part.FindModulesImplementing <PartModule>())
     {
         if (RemoteTech.IsAntenna(m))
         {
             RemoteTech.SetBroken(m, failure);
         }
     }
 }
Ejemplo n.º 8
0
        public void Start()
        {
            Icons.Initialize();                                 // set up the icon textures
            RemoteTech.EnableInSPC();                           // allow RemoteTech Core to run in the Space Center

            // Set the loaded trigger to false, this we will load a new
            // settings after selecting a save game. This is necessary
            // for switching between saves without shutting down the KSP
            // instance.
            //Settings.Instance.SettingsLoaded = false;
        }
Ejemplo n.º 9
0
        public void Start()
        {
            // reset the save game initialized flag
            Kerbalism.IsSaveGameInitDone = false;

            // things in here will be only called once per KSP launch, after loading
            // nearly everything is available at this point, including the Kopernicus patched bodies.
            if (!Kerbalism.IsCoreMainMenuInitDone)
            {
                Kerbalism.IsCoreMainMenuInitDone = true;
            }

            // things in here will be called every the player goes to the main menu
            RemoteTech.EnableInSPC();                               // allow RemoteTech Core to run in the Space Center
        }
Ejemplo n.º 10
0
        public static void Update(Vessel v, Vessel_Info vi, VesselData vd, double elapsed_s)
        {
            // do nothing if signal mechanic is disabled
            if (!Features.Signal && !Features.KCommNet && !RemoteTech.Enabled())
            {
                return;
            }

            // get connection info
            ConnectionInfo conn = vi.connection;

            // maintain and send messages
            // - do not send messages for vessels without an antenna
            // - do not send messages during/after solar storms
            // - do not send messages for EVA kerbals
            if (conn.status != LinkStatus.no_antenna && !v.isEVA && v.situation != Vessel.Situations.PRELAUNCH)
            {
                if (!vd.msg_signal && !conn.linked)
                {
                    vd.msg_signal = true;
                    if (vd.cfg_signal && conn.status != LinkStatus.blackout)
                    {
                        string subtext = "Data transmission disabled";
                        if (vi.crew_count == 0)
                        {
                            switch (Settings.UnlinkedControl)
                            {
                            case UnlinkedCtrl.none: subtext = "Remote control disabled"; break;

                            case UnlinkedCtrl.limited: subtext = "Limited control available"; break;
                            }
                        }
                        Message.Post(Severity.warning, Lib.BuildString("Signal lost with <b>", v.vesselName, "</b>"), subtext);
                    }
                }
                else if (vd.msg_signal && conn.linked)
                {
                    vd.msg_signal = false;
                    if (vd.cfg_signal && !Storm.JustEnded(v, elapsed_s))
                    {
                        var path = conn.path;
                        Message.Post(Severity.relax, Lib.BuildString("<b>", v.vesselName, "</b> signal is back"),
                                     path.Count == 0 ? "We got a direct link with the space center" : Lib.BuildString("Relayed by <b>", path[path.Count - 1].vesselName, "</b>"));
                    }
                }
            }
        }
Ejemplo n.º 11
0
        public static void update(Vessel v, vessel_info vi, VesselData vd, double elapsed_s)
        {
            // do nothing if signal mechanic is disabled
            if (!HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet && !RemoteTech.Enabled())
            {
                return;
            }

            // get connection info
            ConnectionInfo conn = vi.connection;

            // maintain and send messages
            // - do not send messages for vessels without an antenna
            // - do not send messages during/after solar storms
            // - do not send messages for EVA kerbals
            if (conn.status != LinkStatus.no_antenna && !v.isEVA && v.situation != Vessel.Situations.PRELAUNCH)
            {
                if (!vd.msg_signal && !conn.linked)
                {
                    vd.msg_signal = true;
                    if (vd.cfg_signal && conn.status != LinkStatus.blackout)
                    {
                        string subtext = "Data transmission disabled";
                        if (vi.crew_count == 0)
                        {
                            switch (Settings.UnlinkedControl)
                            {
                            case UnlinkedCtrl.none: subtext = Localizer.Format("#KERBALISM_UI_noctrl"); break;

                            case UnlinkedCtrl.limited: subtext = Localizer.Format("#KERBALISM_UI_limitedcontrol"); break;
                            }
                        }
                        Message.Post(Severity.warning, Lib.BuildString(Localizer.Format("#KERBALISM_UI_signallost"), " <b>", v.vesselName, "</b>"), subtext);
                    }
                }
                else if (vd.msg_signal && conn.linked)
                {
                    vd.msg_signal = false;
                    if (vd.cfg_signal && !Storm.JustEnded(v, elapsed_s))
                    {
                        var path = conn.path;
                        Message.Post(Severity.relax, Lib.BuildString("<b>", v.vesselName, "</b> ", Localizer.Format("#KERBALISM_UI_signalback")),
                                     path.Count == 0 ? Localizer.Format("#KERBALISM_UI_directlink") : Lib.BuildString(Localizer.Format("#KERBALISM_UI_relayby"), " <b>", path[path.Count - 1].vesselName, "</b>"));
                    }
                }
            }
        }
Ejemplo n.º 12
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;
                }
            }
        }
Ejemplo n.º 13
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);
            }
        }
Ejemplo n.º 14
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;
            }
        }
Ejemplo n.º 15
0
        public AntennaInfoRT(Vessel v, bool powered, bool storm)
        {
            RemoteTech.SetPoweredDown(v.id, !powered);
            RemoteTech.SetCommsBlackout(v.id, storm);

            // if vessel is loaded, don't calculate ec, RT already handle it.
            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")
                        {
                            ec += 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"));
                            }
                        }
                    }
                }
            }
            // 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;
                    foreach (ProtoPartModuleSnapshot m in p.modules)
                    {
                        // calculate internal (passive) transmitter ec usage @ 0.5W each
                        if (m.moduleName == "ModuleRTAntennaPassive")
                        {
                            ec += 0.0005;
                        }
                        // calculate external transmitters
                        else if (m.moduleName == "ModuleRTAntenna")
                        {
                            // only include data rate and ec cost if transmitter is active
                            if (Lib.Proto.GetBool(m, "IsRTActive"))
                            {
                                bool mFound = false;
                                // get all modules in prefab
                                foreach (PartModule pm in part_prefab.Modules)
                                {
                                    if (pm.moduleName == m.moduleName)
                                    {
                                        mFound = true;
                                        ModuleResource mResource       = pm.resHandler.inputResources.Find(r => r.name == "ElectricCharge");
                                        float?         packet_size     = Lib.SafeReflectionValue <float>(pm, "RTPacketSize");
                                        float?         packet_Interval = Lib.SafeReflectionValue <float>(pm, "RTPacketInterval");

                                        // workaround for old savegames
                                        if (mResource == null || packet_size == null || packet_Interval == null)
                                        {
                                            Lib.LogDebugStack("Old SaveGame PartModule ModuleRTAntenna for part '{0}' on unloaded vessel '{1}', using default values as a workaround", Lib.LogLevel.Message, p.partName, v.vesselName);
                                            Lib.LogDebugStack("ElectricCharge isNull: '{0}', RTPacketSize isNull: '{1}', RTPacketInterval isNull: '{2}'", Lib.LogLevel.Message, mResource == null, packet_size == null, packet_Interval == null);
                                            rate += 6.6666;                                                      // 6.67 Mb/s in 100% factor
                                            ec   += 0.025;                                                       // 25 W/s
                                        }
                                        else
                                        {
                                            rate += (float)packet_size / (float)packet_Interval;
                                            ec   += mResource.rate;
                                        }
                                    }
                                }
                                if (!mFound)
                                {
                                    Lib.LogDebugStack("Could not find PartModule ModuleRTAntenna for part {0} on unloaded vessel {1}, using default values as a workaround", Lib.LogLevel.Message, p.partName, v.vesselName);
                                    rate += 6.6666;                                              // 6.67 Mb/s in 100% factor
                                    ec   += 0.025;                                               // 25 W/s
                                }
                            }
                        }
                    }
                }
            }

            Init(v, powered, storm);
        }
Ejemplo n.º 16
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;
            }

            // 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";
            }
        }
Ejemplo n.º 17
0
        void FixedUpdate()
        {
            // remove control locks in any case
            Misc.clearLocks();

            // do nothing if paused
            if (Lib.IsPaused())
            {
                return;
            }

            // maintain elapsed_s, converting to double only once
            // and detect warp blending
            double fixedDeltaTime = TimeWarp.fixedDeltaTime;

            if (Math.Abs(fixedDeltaTime - elapsed_s) > double.Epsilon)
            {
                warp_blending = 0;
            }
            else
            {
                ++warp_blending;
            }
            elapsed_s = fixedDeltaTime;

            // evict oldest entry from vessel cache
            Cache.update();

            // store info for oldest unloaded vessel
            double           last_time      = 0.0;
            Vessel           last_v         = null;
            vessel_info      last_vi        = null;
            VesselData       last_vd        = null;
            vessel_resources last_resources = null;

            // for each vessel
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                // get vessel info from the cache
                vessel_info vi = Cache.VesselInfo(v);

                // set locks for active vessel
                if (v.isActiveVessel)
                {
                    Misc.setLocks(v, vi);
                }

                // maintain eva dead animation and helmet state
                if (v.loaded && v.isEVA)
                {
                    EVA.update(v);
                }

                // keep track of rescue mission kerbals, and gift resources to their vessels on discovery
                if (v.loaded && vi.is_vessel)
                {
                    // manage rescue mission mechanics
                    Misc.manageRescueMission(v);
                }

                // do nothing else for invalid vessels
                if (!vi.is_valid)
                {
                    continue;
                }

                // get vessel data from db
                VesselData vd = DB.Vessel(v);

                // get resource cache
                vessel_resources resources = ResourceCache.Get(v);

                // if loaded
                if (v.loaded)
                {
                    // show belt warnings
                    Radiation.beltWarnings(v, vi, vd);

                    // update storm data
                    Storm.update(v, vi, vd, elapsed_s);

                    //handle RemoteTech stuff
                    RemoteTech.update(v, vi, vd, elapsed_s);

                    Communications.update(v, vi, vd, elapsed_s);

                    // consume ec for transmission, and transmit science data
                    Science.update(v, vi, vd, resources, elapsed_s);

                    // apply rules
                    Profile.Execute(v, vi, vd, resources, elapsed_s);

                    // apply deferred requests
                    resources.Sync(v, elapsed_s);

                    // call automation scripts
                    vd.computer.automate(v, vi, resources);

                    // remove from unloaded data container
                    unloaded.Remove(vi.id);
                }
                // if unloaded
                else
                {
                    // get unloaded data, or create an empty one
                    unloaded_data ud;
                    if (!unloaded.TryGetValue(vi.id, out ud))
                    {
                        ud = new unloaded_data();
                        unloaded.Add(vi.id, ud);
                    }

                    // accumulate time
                    ud.time += elapsed_s;

                    // maintain oldest entry
                    if (ud.time > last_time)
                    {
                        last_time      = ud.time;
                        last_v         = v;
                        last_vi        = vi;
                        last_vd        = vd;
                        last_resources = resources;
                    }
                }
            }


            // if the oldest unloaded vessel was selected
            if (last_v != null)
            {
                // show belt warnings
                Radiation.beltWarnings(last_v, last_vi, last_vd);

                // update storm data
                Storm.update(last_v, last_vi, last_vd, last_time);

                //handle RemoteTech stuff
                RemoteTech.update(last_v, last_vi, last_vd, last_time);

                Communications.update(last_v, last_vi, last_vd, last_time);

                // consume ec for transmission, and transmit science
                Science.update(last_v, last_vi, last_vd, last_resources, last_time);

                // apply rules
                Profile.Execute(last_v, last_vi, last_vd, last_resources, last_time);

                // simulate modules in background
                Background.update(last_v, last_vi, last_vd, last_resources, last_time);

                // apply deferred requests
                last_resources.Sync(last_v, last_time);

                // call automation scripts
                last_vd.computer.automate(last_v, last_vi, last_resources);

                // remove from unloaded data container
                unloaded.Remove(last_vi.id);
            }

            // update storm data for one body per-step
            if (storm_bodies.Count > 0)
            {
                storm_bodies.ForEach(k => k.time += elapsed_s);
                storm_data sd = storm_bodies[storm_index];
                Storm.update(sd.body, sd.time);
                sd.time     = 0.0;
                storm_index = (storm_index + 1) % storm_bodies.Count;
            }
        }
Ejemplo n.º 18
0
        public static void config(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(20)), " <color=#cccccc>VESSEL CONFIG</color>"));
            p.width(Styles.ScaleWidthFloat(355.0f));
            p.paneltype = Panel.PanelType.config;

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

            // get data from db
            VesselData vd = DB.Vessel(v);

            // toggle rendering
            string tooltip;

            if (Features.Reliability)
            {
                p.section("RENDERING");
            }
            if (Features.Reliability)
            {
                tooltip = "Highlight failed components";
                p.content("highlight malfunctions", string.Empty, tooltip);
                p.icon(vd.cfg_highlights ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_highlights));
            }

            // toggle messages
            p.section("MESSAGES");
            tooltip = "Receive a message when\nElectricCharge level is low";
            p.content("battery", string.Empty, tooltip);
            p.icon(vd.cfg_ec ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_ec));
            if (Features.Supplies)
            {
                tooltip = "Receive a message when\nsupply resources level is low";
                p.content("supply", string.Empty, tooltip);
                p.icon(vd.cfg_supply ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_supply));
            }
            if (RemoteTech.Enabled() || HighLogic.fetch.currentGame.Parameters.Difficulty.EnableCommNet)
            {
                tooltip = "Receive a message when signal is lost or obtained";
                p.content("signal", string.Empty, tooltip);
                p.icon(vd.cfg_signal ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_signal));
            }
            if (Features.Reliability)
            {
                tooltip = "Receive a message\nwhen a component fail";
                p.content("reliability", string.Empty, tooltip);
                p.icon(vd.cfg_malfunction ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_malfunction));
            }
            if (Features.SpaceWeather)
            {
                tooltip = "Receive a message\nduring CME events";
                p.content("storm", string.Empty, tooltip);
                p.icon(vd.cfg_storm ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_storm));
            }
            if (Features.Automation)
            {
                tooltip = "Receive a message when\nscripts are executed";
                p.content("script", string.Empty, tooltip);
                p.icon(vd.cfg_script ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.toggle(ref vd.cfg_script));
            }
        }
Ejemplo n.º 19
0
        // apply type-specific hacks to enable/disable the module
        void Apply(bool b)
        {
            switch (type)
            {
            case "ProcessController":
                if (b)
                {
                    foreach (PartModule m in modules)
                    {
                        Lib.SetResourceFlow(part, (m as ProcessController).resource, false);
                    }
                }
                break;

            case "ModuleDeployableSolarPanel":
            case "ModuleDeployableRadiator":
                if (b)
                {
                    part.FindModelComponents <Animation>().ForEach(k => k.Stop());
                }
                break;

            case "ModuleLight":
                if (b)
                {
                    foreach (PartModule m in modules)
                    {
                        ModuleLight light = m as ModuleLight;
                        if (light.animationName.Length > 0)
                        {
                            new Animator(part, light.animationName).Still(0.0f);
                        }
                        else
                        {
                            part.FindModelComponents <Light>().ForEach(k => k.enabled = false);
                        }
                    }
                }
                break;

            case "ModuleEngines":
            case "ModuleEnginesFX":
                if (b)
                {
                    foreach (PartModule m in modules)
                    {
                        (m as ModuleEngines).Shutdown();
                    }
                }
                break;

            case "ModuleEnginesRF":
                if (b)
                {
                    foreach (PartModule m in modules)
                    {
                        Lib.ReflectionCall(m, "Shutdown");
                    }
                }
                break;

            case "ModuleScienceExperiment":
                if (b)
                {
                    foreach (PartModule m in modules)
                    {
                        (m as ModuleScienceExperiment).SetInoperable();
                    }
                }
                break;
            }

            if (RemoteTech.Enabled)
            {
                foreach (PartModule m in part.FindModulesImplementing <PartModule>())
                {
                    if (RemoteTech.IsAntenna(m))
                    {
                        RemoteTech.SetBroken(m, b);
                    }
                }
            }
        }
Ejemplo n.º 20
0
        bool Render_Vessel(Panel p, Vessel v)
        {
            // get vessel info
            Vessel_Info vi = Cache.VesselInfo(v);

            // skip invalid vessels
            if (!vi.is_valid)
            {
                return(false);
            }

            if (!Lib.IsVessel(v))
            {
                return(false);
            }

            // get data from db
            VesselData vd = DB.Vessel(v);

            // determine if filter must be shown
            show_filter |= vd.group.Length > 0 && vd.group != "NONE";

            // skip filtered vessels
            if (Filtered() && vd.group != filter)
            {
                return(false);
            }

            // get resource handler
            Vessel_Resources resources = ResourceCache.Get(v);

            // get vessel crew
            List <ProtoCrewMember> crew = Lib.CrewList(v);

            // get vessel name
            string vessel_name = v.isEVA ? crew[0].name : v.vesselName;

            // get body name
            string body_name = v.mainBody.name.ToUpper();

            // render entry
            p.SetHeader
            (
                Lib.BuildString("<b>", Lib.Ellipsis(vessel_name, 20), "</b> <size=9><color=#cccccc>", Lib.Ellipsis(body_name, 8), "</color></size>"),
                string.Empty,
                () => { selected_id = selected_id != v.id ? v.id : Guid.Empty; }
            );

            // problem indicator
            Indicator_Problems(p, v, vi, crew);

            // battery indicator
            Indicator_EC(p, v, vi);

            // supply indicator
            if (Features.Supplies)
            {
                Indicator_Supplies(p, v, vi);
            }

            // reliability indicator
            if (Features.Reliability)
            {
                Indicator_Reliability(p, v, vi);
            }

            // signal indicator
            if (Features.Signal || Features.KCommNet || RemoteTech.Enabled())
            {
                Indicator_Signal(p, v, vi);
            }

            // done
            return(true);
        }
Ejemplo n.º 21
0
		void indicator_signal(Panel p, Vessel v, vessel_info vi)
		{
			ConnectionInfo conn = vi.connection;
			if (RemoteTech.Enabled())
			{
				double signal_delay = RemoteTech.GetShortestSignalDelay(v.id);
				string signal_str = "";
				if (signal_delay < Double.Epsilon)
				{
					signal_str = "none";
				}
				else
				{
					signal_str = KSPUtil.dateTimeFormatter.PrintTimeStampCompact(signal_delay, false, false);
				}
				string tooltip_rt = Lib.BuildString(
				  "<align=left />",
				  "connected\t<b>", conn.linked ? "yes" : "no", "</b>\n",
				  "delay\t\t<b>", conn.linked ? signal_str : "no connection", "</b>\n",
				  "rate\t\t<b>", Lib.HumanReadableDataRate(vi.connection.rate), "</b>"
				);
				Texture image_rt = Icons.signal_red;
				if (RemoteTech.Connected(v.id)) image_rt = Icons.signal_white;
				if (RemoteTech.Connected(v.id) && !RemoteTech.ConnectedToKSC(v.id)) image_rt = Icons.signal_yellow;
				if (vi.blackout || RemoteTech.GetCommsBlackout(v.id))
				{
					image_rt = Icons.signal_red;
					tooltip_rt += "\n\n<color=red><i>Blackout</i></color>";
				}
				p.icon(image_rt, tooltip_rt);
				return;
			}

			// target name
			string target_str = string.Empty;
			switch (vi.connection.status)
			{
				case LinkStatus.direct_link: target_str = ("DSN"); break;
				case LinkStatus.indirect_link: target_str = vi.connection.path[vi.connection.path.Count - 1].vesselName; break;
				default: target_str = "none"; break;
			}

			// transmitted label, content and tooltip
			string comms_label = vi.relaying.Length == 0 ? "transmitting" : "relaying";
			string comms_str = vi.connection.linked ? "telemetry" : "nothing";
			string comms_tooltip = string.Empty;
			if (vi.relaying.Length > 0)
			{
				ExperimentInfo exp = Science.experiment(vi.relaying);
				comms_str = exp.name;
				comms_tooltip = exp.fullname;
			}
			else if (vi.transmitting.Length > 0)
			{
				ExperimentInfo exp = Science.experiment(vi.transmitting);
				comms_str = exp.name;
				comms_tooltip = exp.fullname;
			}

			string tooltip = Lib.BuildString
			(
			  "<align=left />",
			  "connected\t<b>", vi.connection.linked ? "yes" : "no", "</b>\n",
			  "rate\t\t<b>", Lib.HumanReadableDataRate(vi.connection.rate), "</b>\n",
			  "target\t\t<b>", target_str, "</b>\n",
			  comms_label, "\t<b>", comms_str, "</b>"
			);

			Texture image = Icons.signal_red;
			switch (conn.status)
			{
				case LinkStatus.direct_link:
					image = vi.connection.rate > 0.005 ? Icons.signal_white : Icons.signal_yellow;
					break;

				case LinkStatus.indirect_link:
					image = vi.connection.rate > 0.005 ? Icons.signal_white : Icons.signal_yellow;
					tooltip += "\n\n<color=yellow>Signal relayed</color>";
					break;

				case LinkStatus.no_link:
					image = Icons.signal_red;
					break;

				case LinkStatus.no_antenna:
					image = Icons.signal_red;
					tooltip += "\n\n<color=red>No antenna</color>";
					break;

				case LinkStatus.blackout:
					image = Icons.signal_red;
					tooltip += "\n\n<color=red><i>Blackout</i></color>";
					break;
			}

			p.icon(image, tooltip);
		}