コード例 #1
0
        public void ProcessActionGroup()
        {
            var vessel = FlightGlobals.FindVessel(VesselId);

            if (vessel == null)
            {
                return;
            }

            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            //Ignore SAS if we are spectating as it will fight with the FI
            if (ActionGroup == KSPActionGroup.SAS && VesselCommon.IsSpectating && FlightGlobals.ActiveVessel && FlightGlobals.ActiveVessel.id == vessel.id)
            {
                return;
            }

            if (vessel.ActionGroups != null)
            {
                var currentValue = vessel.ActionGroups[ActionGroup];
                if (currentValue != Value)
                {
                    vessel.ActionGroups.ToggleGroup(ActionGroup);
                }
            }

            vessel.protoVessel?.actionGroups.SetValue(ActionGroup.ToString(), $"{Value.ToString(CultureInfo.InvariantCulture)}, 0");
        }
コード例 #2
0
 private void RunCheck(Guid vesselId, string experimentId, ExperimentState state)
 {
     if (experimentId == this.experimentId)
     {
         CheckVessel(FlightGlobals.FindVessel(vesselId));
     }
 }
コード例 #3
0
        /// <summary>
        /// Get the vessels that are in a past subspace and kill them
        /// </summary>
        private IEnumerator RemoveVesselsInPastSubspace()
        {
            var seconds = new WaitForSeconds((float)TimeSpan.FromMilliseconds(SettingsSystem.ServerSettings.VesselKillCheckMsInterval).TotalSeconds);

            while (true)
            {
                try
                {
                    if (!Enabled)
                    {
                        break;
                    }

                    if (MainSystem.Singleton.GameRunning)
                    {
                        var vesselsToUnload = VesselProtoSystem.Singleton.AllPlayerVessels
                                              .Where(v => v.Loaded && VesselCommon.VesselIsControlledAndInPastSubspace(v.VesselId))
                                              .Select(v => FlightGlobals.FindVessel(v.VesselId))
                                              .ToArray();

                        if (vesselsToUnload.Any())
                        {
                            Debug.Log($"[LMP]: Unloading {vesselsToUnload.Length} vessels that are in a past subspace");
                            UnloadVessels(vesselsToUnload);
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.LogError($"[LMP]: Coroutine error in CheckVesselsToKill {e}");
                }

                yield return(seconds);
            }
        }
コード例 #4
0
        /// <summary>
        /// Here we wait until we fully switched to the dominant vessel and THEN we send the vessel dock information.
        /// We wait 5 seconds before sending the data to give time to the dominant vessel to detect the dock
        /// </summary>
        private static IEnumerator WaitUntilWeSwitchedThenSendDockInfo(Guid weakId, Guid dominantId, int secondsToWait = 5)
        {
            var start             = LunaComputerTime.UtcNow;
            var currentSubspaceId = WarpSystem.Singleton.CurrentSubspace;
            var waitInterval      = new WaitForSeconds(0.5f);

            while (FlightGlobals.ActiveVessel?.id != dominantId && LunaComputerTime.UtcNow - start < TimeSpan.FromSeconds(30))
            {
                yield return(waitInterval);
            }

            if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.id == dominantId)
            {
                /* We are NOT the dominant vessel so wait 5 seconds so the dominant vessel detects the docking.
                 * If we send the vessel definition BEFORE the dominant detects it, then the dominant won't be able
                 * to undock properly as he will think that he is the weak vessel.
                 */

                yield return(new WaitForSeconds(secondsToWait));

                FlightGlobals.ActiveVessel.BackupVessel();
                LunaLog.Log($"[LMP]: Sending dock info to the server! Final dominant vessel parts {FlightGlobals.ActiveVessel.protoVessel.protoPartSnapshots.Count}");

                System.MessageSender.SendDockInformation(weakId, FlightGlobals.FindVessel(dominantId), currentSubspaceId, FlightGlobals.ActiveVessel.protoVessel);
            }
        }
コード例 #5
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselFairingMsgData msgData) || !System.FairingSystemReady)
            {
                return;
            }

            //Vessel might exist in the store but not in game (if the vessel is in safety bubble for example)
            VesselsProtoStore.UpdateVesselProtoPartFairing(msgData);

            var vessel = FlightGlobals.FindVessel(msgData.VesselId);

            if (vessel == null)
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, msgData.PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, "ModuleProceduralFairing");
                module?.moduleValues.SetValue("fsm", "st_flight_deployed");
                module?.moduleValues.RemoveNodesStartWith("XSECTION");

                (module?.moduleRef as ModuleProceduralFairing)?.DeployFairing();
            }
        }
コード例 #6
0
        public void HandleMessage(IMessageData messageData)
        {
            var msgData = messageData as VesselDockMsgData;

            if (msgData == null)
            {
                return;
            }

            LunaLog.Log("[LMP]: Docking message received!");

            if (FlightGlobals.ActiveVessel?.id == msgData.WeakVesselId)
            {
                LunaLog.Log("[LMP]: Docking NOT detected. We DON'T OWN the dominant vessel");

                SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.ActiveVessel, true);
                SystemsContainer.Get <VesselSwitcherSystem>().SwitchToVessel(msgData.DominantVesselId);
            }
            if (FlightGlobals.ActiveVessel?.id == msgData.DominantVesselId && !VesselCommon.IsSpectating)
            {
                var newProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData);

                if (VesselCommon.ProtoVesselHasChanges(FlightGlobals.ActiveVessel.protoVessel, newProto))
                {
                    LunaLog.Log("[LMP]: Docking NOT detected. We OWN the dominant vessel");
                    //We own the dominant vessel and dind't detected the docking event so we need to reload our OWN vessel
                    //so if we send our own protovessel later, we send the updated definition
                    SystemsContainer.Get <VesselProtoSystem>().VesselLoader.ReloadVessel(newProto);
                }
            }

            //Some other 2 players docked so just remove the weak vessel.
            SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.FindVessel(msgData.WeakVesselId), true);
            SystemsContainer.Get <VesselProtoSystem>().HandleVesselProtoData(msgData.FinalVesselData, msgData.DominantVesselId);
        }
コード例 #7
0
        /// <summary>
        /// When a stage of ANY vessel is separated, try to get the update lock of that debris
        /// </summary>
        /// <param name="data"></param>
        public void OnStageSeparation(EventReport data)
        {
            if (!VesselCommon.IsSpectating)
            {
                var debrisVessel = FlightGlobals.FindVessel(data.origin.vessel.id);
                var missionId    = data.origin.missionID;

                if (!SystemsContainer.Get <LockSystem>().LockWithPrefixExists($"debris-{missionId}"))
                {
                    SystemsContainer.Get <LockSystem>().AcquireLock($"debris-{missionId}_{debrisVessel.id}");
                    SystemsContainer.Get <VesselPositionSystem>().MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel));
                }
                else
                {
                    var debrisLocks = SystemsContainer.Get <LockSystem>().ServerLocks.Where(l => l.Key.StartsWith($"debris-{missionId}"))
                                      .Select(l => l.Key.Substring(l.Key.IndexOf('_') + 1)).ToArray();

                    var otherVesselsWIthSameMissionId = FlightGlobals.Vessels
                                                        .Where(v => v.Parts.Any() && v.Parts.First().missionID == missionId && v.id != debrisVessel.id)
                                                        .Select(v => v.id.ToString()).ToArray();

                    if (debrisLocks.Length == otherVesselsWIthSameMissionId.Length)
                    {
                        debrisVessel.id = new Guid(debrisLocks.Except(otherVesselsWIthSameMissionId).First());
                    }
                    else
                    {
                        SystemsContainer.Get <LockSystem>().AcquireLock($"debris-{missionId}_{debrisVessel.id}");
                        SystemsContainer.Get <VesselPositionSystem>().MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel));
                    }
                }
            }
        }
コード例 #8
0
        public void ProcessPartMethodCallSync()
        {
            var vessel = FlightGlobals.FindVessel(VesselId);

            if (vessel == null || !vessel.loaded)
            {
                return;
            }

            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            var part = vessel.protoVessel.GetProtoPart(PartFlightId);

            if (part != null)
            {
                var module = part.FindProtoPartModuleInProtoPart(ModuleName);
                if (module != null)
                {
                    if (module.moduleRef != null)
                    {
                        module.moduleRef.GetType().GetMethod(MethodName, AccessTools.all)?.Invoke(module.moduleRef, null);
                        PartModuleEvent.onPartModuleMethodProcessed.Fire(module, MethodName);
                    }
                }
            }
        }
コード例 #9
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselEvaMsgData msgData) || !System.EvaSystemReady)
            {
                return;
            }

            //We received a msg for our own controlled vessel so ignore it
            if (LockSystem.LockQuery.ControlLockBelongsToPlayer(msgData.VesselId, SettingsSystem.CurrentSettings.PlayerName))
            {
                return;
            }

            //Vessel might exist in the store but not in game (if the vessel is in safety bubble for example)
            VesselsProtoStore.UpdateVesselProtoEvaFsm(msgData);

            var vessel = FlightGlobals.FindVessel(msgData.VesselId);

            if (vessel == null || !vessel.isEVA)
            {
                return;
            }

            try
            {
                System.RunEvent(vessel, msgData.NewState, msgData.EventToRun);
            }
            catch (Exception)
            {
                //Ignore the eva animation errors
            }
        }
コード例 #10
0
        public void HandleDocking(Guid from, Guid to)
        {
            var fromVessel = FlightGlobals.FindVessel(from);
            var toVessel   = FlightGlobals.FindVessel(to);

            var finalVessel = fromVessel != null && toVessel != null
                ? Vessel.GetDominantVessel(fromVessel, toVessel)
                : fromVessel ?? toVessel;

            if (finalVessel != null)
            {
                var vesselIdToRemove = finalVessel.id == from ? to : from;

                if (finalVessel == FlightGlobals.ActiveVessel)
                {
                    LunaLog.Log($"[LMP]: Docking: We own the dominant vessel {finalVessel.id}");
                }
                else
                {
                    LunaLog.Log($"[LMP]: Docking: We DON'T own the dominant vessel {finalVessel.id}. Switching");
                    FlightGlobals.SetActiveVessel(finalVessel);
                }

                SystemsContainer.Get <VesselProtoSystem>().RemoveVesselFromLoadingSystem(vesselIdToRemove);
                SystemsContainer.Get <VesselRemoveSystem>().MessageSender.SendVesselRemove(vesselIdToRemove, true);

                LunaLog.Log("[LMP]: Docking event over!");
            }
        }
コード例 #11
0
        IEnumerator <YieldInstruction> CompleteVesselLoad(string key, Guid id)
        {
            if (FlightGlobals.Vessels.Count == 0)
            {
                yield return(new WaitForEndOfFrame());
            }

            if (!vessels.ContainsKey(key))
            {
                yield break;
            }

            VesselInfo vi     = vessels[key];
            Vessel     vessel = FlightGlobals.FindVessel(id);

            if (vessel == null || vessel.state == Vessel.State.DEAD)
            {
                id = Guid.Empty;
                vessels.Remove(key);
            }
            else if (vi.hash == 0 && HighLogic.LoadedScene == GameScenes.FLIGHT)
            {
                vi.hash = vessel.GetHashes().FirstOrDefault();
                LoggingUtil.LogVerbose(this, "Setting hash for " + id + " on load to: " + vi.hash);
            }
        }
コード例 #12
0
 public static InterestedVessel Load(ConfigNode node)
 {
     if (node.HasValue("VesselGuid"))
     {
         Guid id = new Guid(node.GetValue("VesselGuid"));
         if (FlightGlobals.fetch)
         {
             Vessel vsl = FlightGlobals.FindVessel(id);
             if (vsl != null)
             {
                 if (vsl.protoVessel != null)
                 {
                     ProtoVessel      protovsl         = vsl.protoVessel;
                     InterestedVessel interestedVessel = new InterestedVessel(vsl, protovsl);
                     node.TryGetValue("timeLastRefresh", ref interestedVessel.TimeLastRefresh);
                     ConfigNode[] cacheResourcesNodes = node.GetNodes("CACHERESOURCE");
                     for (int crI = 0; crI < cacheResourcesNodes.Length; crI++)
                     {
                         CacheResources.CacheResource cacheResource = CacheResources.CacheResource.Load(cacheResourcesNodes[crI], protovsl);
                         if (cacheResource != null)
                         {
                             interestedVessel.CachedResources.Add(cacheResource);
                         }
                     }
                     return(interestedVessel);
                 }
             }
         }
     }
     return(null);
 }
コード例 #13
0
        /// <summary>
        /// If short_strings parameter is true then the strings used for display of the data will be shorter when inflight.
        /// </summary>
        public static void Fileman(this Panel p, Vessel v, bool short_strings = false)
        {
            // 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>FILE MANAGER</color>"));
            p.Width(Styles.ScaleWidthFloat(465.0f));
            p.paneltype = Panel.PanelType.data;

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

            // get vessel drive
            Drive drive = DB.Vessel(v).drive;

            // draw data section
            p.AddSection("DATA");
            foreach (var pair in drive.files)
            {
                string filename = pair.Key;
                File   file     = pair.Value;
                Render_file(p, filename, file, drive, short_strings && Lib.IsFlight(), Cache.VesselInfo(v).connection.rate);
            }
            if (drive.files.Count == 0)
            {
                p.AddContent("<i>no files</i>", string.Empty);
            }

            // draw samples section
            p.AddSection("SAMPLES");
            foreach (var pair in drive.samples)
            {
                string filename = pair.Key;
                Sample sample   = pair.Value;
                Render_sample(p, filename, sample, drive, short_strings && Lib.IsFlight());
            }
            if (drive.samples.Count == 0)
            {
                p.AddContent("<i>no samples</i>", string.Empty);
            }
        }
コード例 #14
0
		public void update()
		{
			// reset panel
			panel.clear();

			// get vessel
			selected_v = selected_id == Guid.Empty ? null : FlightGlobals.FindVessel(selected_id);

			// if nothing is selected, or if the selected vessel doesn't exist
			// anymore, or if it has become invalid for whatever reason
			if (selected_v == null || !Cache.VesselInfo(selected_v).is_valid)
			{
				// forget the selected vessel, if any
				selected_id = Guid.Empty;

				// filter flag is updated on render_vessel
				show_filter = false;

				// used to detect when no vessels are in list
				bool setup = false;

				// draw active vessel if any
				if (FlightGlobals.ActiveVessel != null)
				{
					setup |= render_vessel(panel, FlightGlobals.ActiveVessel);
				}

				// for each vessel
				foreach (Vessel v in FlightGlobals.Vessels)
				{
					// skip active vessel
					if (v == FlightGlobals.ActiveVessel) continue;

					// draw the vessel
					setup |= render_vessel(panel, v);
				}

				// empty vessel case
				if (!setup)
				{
					panel.header("<i>no vessels</i>");
				}
			}
			// if a vessel is selected
			else
			{
				// header act as title
				render_vessel(panel, selected_v);

				// update page content
				switch (page)
				{
					case MonitorPage.telemetry: panel.telemetry(selected_v); break;
					case MonitorPage.data: panel.fileman(selected_v, true); break;  // Using short_strings parameter to stop overlapping when inflight.
					case MonitorPage.scripts: panel.devman(selected_v); break;
					case MonitorPage.config: panel.config(selected_v); break;
					case MonitorPage.log: panel.logman(selected_v); break;
				}
			}
		}
コード例 #15
0
        /// <summary>
        /// Make the other player vessels inmortal
        /// </summary>
        private void MakeOtherPlayerVesselsImmortal()
        {
            if (Enabled && VesselImmortalSystemReady)
            {
                var ownedVessels = SystemsContainer.Get <LockSystem>().GetOwnedLocksPrefix("control-").Select(LockSystem.TrimLock)
                                   .Union(SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("update-").Select(LockSystem.TrimLock))
                                   .Select(i => FlightGlobals.FindVessel(new Guid(i)))
                                   .Where(v => v != null)
                                   .ToArray();

                var othersPeopleVessels = SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("control-").Select(LockSystem.TrimLock)
                                          .Union(SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("update-").Select(LockSystem.TrimLock))
                                          .Except(ownedVessels.Select(v => v.id.ToString()))
                                          .Select(i => FlightGlobals.FindVessel(new Guid(i)))
                                          //Select the vessels and filter out the nulls
                                          .Where(v => v != null).ToArray();

                foreach (var vessel in ownedVessels)
                {
                    SetVesselImmortalState(vessel, false);
                }

                foreach (var vessel in othersPeopleVessels)
                {
                    SetVesselImmortalState(vessel, true);
                }
            }
        }
コード例 #16
0
        protected override void PrintDisplay()
        {
            GUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.Label(VesselName);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Reload"))
            {
                var vessel = FlightGlobals.FindVessel(VesselId);

                //Do not call BackupVessel() as that would overwrite the proto with the actual vessel values and mess up part syncs
                VesselLoader.LoadVessel(vessel.protoVessel, true);
            }
            GUILayout.EndHorizontal();

            Data.Display = GUILayout.Toggle(Data.Display, nameof(Data), ButtonStyle);
            Data.Print();
            Locks.Display = GUILayout.Toggle(Locks.Display, nameof(Locks), ButtonStyle);
            Locks.Print();
            Orbit.Display = GUILayout.Toggle(Orbit.Display, nameof(Orbit), ButtonStyle);
            Orbit.Print();
            Interpolation.Display = GUILayout.Toggle(Interpolation.Display, nameof(Interpolation), ButtonStyle);
            Interpolation.Print();
            Position.Display = GUILayout.Toggle(Position.Display, nameof(Position), ButtonStyle);
            Position.Print();
            Vectors.Display = GUILayout.Toggle(Vectors.Display, nameof(Vectors), ButtonStyle);
            Vectors.Print();
            GUILayout.EndVertical();
        }
コード例 #17
0
        /// <summary>
        /// Kills and unloads a vessel.
        /// </summary>
        public void KillVessel(Guid vesselId, string reason, bool switchVessel = true, bool removeFromStore = true)
        {
            //ALWAYS remove it from the proto store as this dictionary is maintained even if we are in the KSC
            //This means that while in KSC if we receive a vessel remove msg, our FlightGlobals.Vessels will be empty
            //But our VesselsProtoStore probably contains that vessel that must be removed.
            if (removeFromStore)
            {
                VesselsProtoStore.RemoveVessel(vesselId);
                VesselPositionSystem.Singleton.RemoveVessel(vesselId);
                VesselFlightStateSystem.Singleton.RemoveVessel(vesselId);
            }
            var killVessel = FlightGlobals.FindVessel(vesselId);

            if (killVessel == null || killVessel.state == Vessel.State.DEAD)
            {
                return;
            }

            LunaLog.Log($"[LMP]: Killing vessel {killVessel.id}. Reason: {reason}");
            if (switchVessel)
            {
                SwitchVesselIfSpectating(killVessel);
            }

            UnloadVesselFromGame(killVessel);
            KillGivenVessel(killVessel);
            UnloadVesselFromScenario(killVessel);

            //When vessel.Die() is called, KSP calls RefreshMarkers() so no need to call it ourselves
        }
コード例 #18
0
        /// <summary>
        /// When a stage of ANY vessel is separated, try to get the update lock of that debris
        /// </summary>
        /// <param name="data"></param>
        public void OnStageSeparation(EventReport data)
        {
            if (!VesselCommon.IsSpectating && !VesselCommon.ActiveVesselIsInSafetyBubble())
            {
                var debrisVessel = FlightGlobals.FindVessel(data.origin.vessel.id);
                var missionId    = data.origin.missionID;

                if (!LockSystem.Singleton.LockWithPrefixExists("debris-" + missionId))
                {
                    LockSystem.Singleton.AcquireLock("debris-" + missionId + "_" + debrisVessel.id);
                    VesselPositionSystem.Singleton.MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel));
                }
                else
                {
                    var debrisLocks = LockSystem.Singleton.ServerLocks.Where(l => l.Key.StartsWith("debris-" + missionId))
                                      .Select(l => l.Key.Substring(l.Key.IndexOf('_') + 1)).ToArray();

                    var otherVesselsWIthSameMissionId = FlightGlobals.Vessels
                                                        .Where(v => v.Parts.Any() && v.Parts.First().missionID == missionId && v.id != debrisVessel.id)
                                                        .Select(v => v.id.ToString()).ToArray();

                    if (debrisLocks.Length == otherVesselsWIthSameMissionId.Length)
                    {
                        debrisVessel.id = new Guid(debrisLocks.Except(otherVesselsWIthSameMissionId).First());
                    }
                    else
                    {
                        LockSystem.Singleton.AcquireLock("debris-" + missionId + "_" + debrisVessel.id);
                        VesselPositionSystem.Singleton.MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel));
                    }
                }
            }
        }
コード例 #19
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselUpdateMsgData msgData) || !System.UpdateSystemReady)
            {
                return;
            }

            //We received a msg for our own controlled/updated vessel so ignore it
            if (!VesselCommon.DoVesselChecks(msgData.VesselId))
            {
                return;
            }

            //Vessel might exist in the store but not in game (if the vessel is in safety bubble for example)
            VesselsProtoStore.UpdateVesselProtoValues(msgData);

            var vessel = FlightGlobals.FindVessel(msgData.VesselId);

            if (vessel == null)
            {
                return;
            }

            UpdateVesselFields(vessel, msgData);
            UpdateActionGroups(vessel, msgData);
            UpdateProtoVesselValues(vessel.protoVessel, msgData);
        }
コード例 #20
0
ファイル: AntennaInfoRT.cs プロジェクト: tinygrox/Kerbalism
        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;
            }
        }
コード例 #21
0
        public static void FileMan(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, 20), " <color=#cccccc>FILE MANAGER</color>"));
            p.Width(320.0f);

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

            // get vessel drive
            Drive drive = DB.Vessel(v).drive;

            // draw data section
            p.SetSection("DATA");
            foreach (var pair in drive.files)
            {
                string filename = pair.Key;
                File   file     = pair.Value;
                Render_File(p, filename, file, drive);
            }
            if (drive.files.Count == 0)
            {
                p.SetContent("<i>no files</i>", string.Empty);
            }

            // draw samples section
            p.SetSection("SAMPLES");
            foreach (var pair in drive.samples)
            {
                string filename = pair.Key;
                Sample sample   = pair.Value;
                Render_Sample(p, filename, sample, drive);
            }
            if (drive.samples.Count == 0)
            {
                p.SetContent("<i>no samples</i>", string.Empty);
            }
        }
コード例 #22
0
 /// <summary>
 /// Gets the vessel associated with the given key.
 /// </summary>
 /// <param name="key">The key to find an associated vessel for.</param>
 /// <returns>The vessel that is associated to the given key or null if none.</returns>
 public Vessel GetAssociatedVessel(string key)
 {
     if (vessels.ContainsKey(key))
     {
         return(FlightGlobals.FindVessel(vessels[key].id));
     }
     return(null);
 }
コード例 #23
0
 /// <summary>
 /// Specifies the vessel that we should switch to
 /// </summary>
 public void SwitchToVessel(Guid vesselId)
 {
     VesselToSwitchTo = FlightGlobals.FindVessel(vesselId);
     if (VesselToSwitchTo != null)
     {
         LunaLog.Log($"[LMP]: Switching to vessel {vesselId}");
     }
 }
コード例 #24
0
        private void Init(Vessel v, bool powered, bool storm)
        {
            if (!powered || v.connection == null)
            {
                linked = false;
                status = (int)LinkStatus.no_link;
                return;
            }

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

            // are we connected to DSN
            if (v.connection.IsConnected)
            {
                linked = true;
                var link = v.connection.ControlPath.First;
                status   = link.hopType == CommNet.HopType.Home ? (int)LinkStatus.direct_link : (int)LinkStatus.indirect_link;
                strength = link.signalStrength;

                rate *= Math.Pow(link.signalStrength, Settings.DataRateDampingExponent);

                target_name = Lib.Ellipsis(Localizer.Format(v.connection.ControlPath.First.end.displayName).Replace("Kerbin", "DSN"), 20);

                if (status != (int)LinkStatus.direct_link)
                {
                    Vessel firstHop = Lib.CommNodeToVessel(v.Connection.ControlPath.First.end);
                    // Get rate from the firstHop, each Hop will do the same logic, then we will have the min rate for whole path
                    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 = (int)LinkStatus.plasma;
            }

            control_path = new List <string[]>();
            foreach (CommLink link in v.connection.ControlPath)
            {
                double antennaPower   = link.end.isHome ? link.start.antennaTransmit.power + link.start.antennaRelay.power : link.start.antennaTransmit.power;
                double signalStrength = 1 - ((link.start.position - link.end.position).magnitude / Math.Sqrt(antennaPower * link.end.antennaRelay.power));
                signalStrength = (3 - (2 * signalStrength)) * Math.Pow(signalStrength, 2);

                string name    = Lib.Ellipsis(Localizer.Format(link.end.name).Replace("Kerbin", "DSN"), 35);
                string value   = Lib.HumanReadablePerc(Math.Ceiling(signalStrength * 10000) / 10000, "F2");
                string tooltip = "Distance: " + 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));
                control_path.Add(new string[] { name, value, tooltip });
            }

            if (linked)
            {
            }
        }
コード例 #25
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselDockMsgData msgData))
            {
                return;
            }

            LunaLog.Log("Docking message received!");

            //Add the new vessel data to the store
            VesselsProtoStore.HandleVesselProtoData(msgData.FinalVesselData, msgData.NumBytes, msgData.DominantVesselId);

            if (FlightGlobals.ActiveVessel?.id == msgData.WeakVesselId)
            {
                LunaLog.Log($"Docking NOT detected. We DON'T OWN the dominant vessel. Switching to {msgData.DominantVesselId}");

                SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.ActiveVessel.id);
                SystemsContainer.Get <VesselSwitcherSystem>().SwitchToVessel(msgData.DominantVesselId);

                WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId);
            }
            if (FlightGlobals.ActiveVessel?.id == msgData.DominantVesselId && !VesselCommon.IsSpectating)
            {
                var newProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData, msgData.NumBytes);

                /* This is a strange case were we didn't detect the docking on time and the weak vessel send the new definition...
                 * Usually it happens when a vessel in a future subspace docks with a vessel in the past and the vessel in the past is the dominant vessel
                 * The reason why is bad is because the ModuleDockingNode sent by the WEAK vessel will tell us that we are
                 * NOT the dominant (because we received the vesselproto from the WEAK vessel) so we won't be able to undock properly...
                 * This will be fixed if we go to the space center and reload again the vessel...
                 */
                LunaLog.Log("Docking NOT detected. We OWN the dominant vessel");

                if (FlightGlobals.FindVessel(msgData.WeakVesselId) != null)
                {
                    LunaLog.Log($"Weak vessel {msgData.WeakVesselId} still exists in our game. Removing it now");
                    SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(msgData.WeakVesselId);
                    SystemsContainer.Get <VesselRemoveSystem>().KillVessel(msgData.WeakVesselId);
                }

                /* We own the dominant vessel and dind't detected the docking event so we need to reload our OWN vessel
                 * so if we send our own protovessel later, we send the updated definition
                 */
                LunaLog.Log($"Creating the missing parts in our own vessel. Current: {FlightGlobals.ActiveVessel.parts.Count} Expected: {newProto.protoPartSnapshots.Count}");
                //ProtoToVesselRefresh.CreateMissingPartsInCurrentProtoVessel(FlightGlobals.ActiveVessel, newProto);
                VesselLoader.ReloadVessel(newProto);

                LunaLog.Log("Force sending the new proto vessel");
                SystemsContainer.Get <VesselProtoSystem>().MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel, true);

                WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId);
                return;
            }

            //Some other 2 players docked so just remove the weak vessel.
            SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(msgData.WeakVesselId);
        }
コード例 #26
0
        void focusVessel()
        {
            var vsl = FlightGlobals.FindVessel(vessel.id);

            if (vsl != null)
            {
                toMapView(vsl.mapObject);
            }
        }
コード例 #27
0
 /// <summary>
 /// Specifies the vessel that we should switch to
 /// </summary>
 public void SwitchToVessel(Guid vesselId)
 {
     VesselToSwitchTo = FlightGlobals.FindVessel(vesselId);
     if (VesselToSwitchTo != null)
     {
         LunaLog.Log($"[LMP]: Switching to vessel {vesselId}");
         Client.Singleton.StartCoroutine(SwitchToVessel());
     }
 }
コード例 #28
0
        /// <summary>
        /// Find the vessel using the lock name
        /// </summary>
        private void UpdateVesselColorsFromLockVesselId(Guid vesselId)
        {
            var vessel = FlightGlobals.FindVessel(vesselId);

            if (vessel != null)
            {
                System.SetVesselOrbitColor(vessel);
            }
        }
コード例 #29
0
        public static void Failman(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 data
            VesselData vd = v.KerbalismData();

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

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(20)), " ", Lib.Color("Quality Management", Lib.Kolor.LightGrey)));
            p.Width(Styles.ScaleWidthFloat(355.0f));
            p.paneltype = Panel.PanelType.failures;

            string section = string.Empty;

            // get devices
            List <ReliabilityInfo> devices = vd.ReliabilityStatus();

            int deviceCount = 0;

            // for each device
            foreach (var ri in devices)
            {
                if (section != Group2Section(ri.group))
                {
                    section = Group2Section(ri.group);
                    p.AddSection(section);
                }

                string status = StatusString(ri);

                // render device entry
                p.AddContent(
                    label: ri.title,
                    value: status,
                    hover: () => Highlighter.Set(ri.partId, Color.blue));
                deviceCount++;
            }

            // no devices case
            if (deviceCount == 0)
            {
                p.AddContent("<i>no quality info</i>");
            }
        }
コード例 #30
0
        /// <summary>
        /// Check vessels that must be loaded
        /// </summary>
        public void CheckVesselsToLoad()
        {
            if (HighLogic.LoadedScene < GameScenes.SPACECENTER)
            {
                return;
            }

            try
            {
                foreach (var keyVal in VesselProtos)
                {
                    if (keyVal.Value.TryPeek(out var vesselProto) && vesselProto.GameTime <= TimeSyncSystem.UniversalTime)
                    {
                        keyVal.Value.TryDequeue(out _);

                        if (VesselRemoveSystem.VesselWillBeKilled(vesselProto.VesselId))
                        {
                            continue;
                        }

                        var forceReload = vesselProto.ForceReload;
                        var protoVessel = vesselProto.CreateProtoVessel();
                        keyVal.Value.Recycle(vesselProto);

                        if (protoVessel == null || protoVessel.HasInvalidParts(!VesselsUnableToLoad.Contains(vesselProto.VesselId)))
                        {
                            VesselsUnableToLoad.Add(vesselProto.VesselId);
                            continue;
                        }

                        VesselsUnableToLoad.Remove(vesselProto.VesselId);

                        var existingVessel = FlightGlobals.FindVessel(vesselProto.VesselId);
                        if (existingVessel == null)
                        {
                            if (VesselLoader.LoadVessel(protoVessel, forceReload))
                            {
                                LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} loaded");
                                VesselLoadEvent.onLmpVesselLoaded.Fire(protoVessel.vesselRef);
                            }
                        }
                        else
                        {
                            if (VesselLoader.LoadVessel(protoVessel, forceReload))
                            {
                                LunaLog.Log($"[LMP]: Vessel {protoVessel.vesselID} reloaded");
                                VesselReloadEvent.onLmpVesselReloaded.Fire(protoVessel.vesselRef);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error in CheckVesselsToLoad {e}");
            }
        }