Пример #1
0
        /// <summary>Removes a ground station from the list by its unique <paramref name="stationid"/>.</summary>
        /// <param name="stationid">Unique ground station id</param>
        /// <returns>Returns true for a successful removed station, otherwise false.</returns>
        public bool RemoveGroundStation(Guid stationid)
        {
            RTLog.Notify("Trying to remove ground station {0}", RTLogLevel.LVL1, stationid);

            for (var i = 0; i < GroundStations.Count; i++)
            {
                if (!GroundStations[i].mGuid.Equals(stationid))
                {
                    continue;
                }

                RTLog.Notify("Removing {0} ", RTLogLevel.LVL1, GroundStations[i].GetName());
                GroundStations.RemoveAt(i);
                Save();
                return(true);
            }

            RTLog.Notify("Cannot find station {0}", RTLogLevel.LVL1, stationid);
            return(false);
        }
Пример #2
0
        public void Unregister(Guid key, IAntenna antenna)
        {
            RTLog.Notify("AntennaManager: Unregister({0})", antenna);

            if (!mLoadedAntennaCache.ContainsKey(key))
            {
                return;
            }

            int instance_id = mLoadedAntennaCache[key].FindIndex(x => x == antenna);

            if (instance_id != -1)
            {
                mLoadedAntennaCache[key].RemoveAt(instance_id);
                if (mLoadedAntennaCache[key].Count == 0)
                {
                    mLoadedAntennaCache.Remove(key);
                }
                OnUnregister(antenna);
            }
        }
Пример #3
0
 public static ISignalProcessor GetSignalProcessor(this Vessel v)
 {
     RTLog.Notify("GetSignalProcessor({0}): Check", v.vesselName);
     if (v.loaded)
     {
         foreach (PartModule pm in v.Parts.SelectMany(p => p.Modules.Cast <PartModule>()).Where(pm => pm.IsSignalProcessor()))
         {
             RTLog.Notify("GetSignalProcessor({0}): Found", v.vesselName);
             return(pm as ISignalProcessor);
         }
     }
     else
     {
         foreach (ProtoPartModuleSnapshot ppms in v.protoVessel.protoPartSnapshots.SelectMany(x => x.modules).Where(ppms => ppms.IsSignalProcessor()))
         {
             RTLog.Notify("GetSignalProcessor({0}): Found", v.vesselName);
             return(new ProtoSignalProcessor(ppms, v));
         }
     }
     return(null);
 }
Пример #4
0
        /// <summary>
        /// Registers a protosatellite compiled from the unloaded vessel data.
        /// </summary>
        /// <param name="vessel">The vessel.</param>
        public void RegisterProto(Vessel vessel)
        {
            Guid key = vessel.protoVessel.vesselID;

            RTLog.Notify("SatelliteManager: RegisterProto({0}, {1})", vessel.vesselName, key);
            // Return if there are still signal processors loaded.
            if (mLoadedSpuCache.ContainsKey(vessel.id))
            {
                mLoadedSpuCache.Remove(vessel.id);
            }

            ISignalProcessor spu = vessel.GetSignalProcessor();

            if (spu != null)
            {
                List <ISignalProcessor> protos = new List <ISignalProcessor>();
                protos.Add(spu);
                mSatelliteCache[key] = new VesselSatellite(protos);
                OnRegister(mSatelliteCache[key]);
            }
        }
Пример #5
0
        public static Settings Load()
        {
            // Create a new settings object
            Settings settings = new Settings();
            // try to load from the base settings.cfg
            ConfigNode load = ConfigNode.Load(File);

            if (load == null)
            {
                // write new base file to the rt folder
                settings.Save();
            }
            else
            {
                // old or new format?
                if (load.HasNode("RemoteTechSettings"))
                {
                    load = load.GetNode("RemoteTechSettings");
                }
                RTLog.Notify("Load base settings into object with {0}", load);
                // load basic file
                ConfigNode.LoadObjectFromConfig(settings, load);
            }

            // Prefer to load from GameDatabase, to allow easier user customization
            UrlDir.UrlConfig[] configList = GameDatabase.Instance.GetConfigs("RemoteTechSettings");
            foreach (UrlDir.UrlConfig curSet in configList)
            {
                // only third party files
                if (!curSet.url.Equals("RemoteTech/RemoteTech_Settings/RemoteTechSettings"))
                {
                    RTLog.Notify("Override RTSettings with configs from {0}", curSet.url);
                    settings.backupFields();
                    ConfigNode.LoadObjectFromConfig(settings, curSet.config);
                    settings.restoreBackups();
                }
            }

            return(settings);
        }
Пример #6
0
        /// <summary>
        /// Unregisters the specified signal processor.
        /// </summary>
        /// <param name="key">The key the signal processor was registered under.</param>
        /// <param name="spu">The signal processor.</param>
        public void Unregister(Guid key, ISignalProcessor spu)
        {
            RTLog.Notify("SatelliteManager: Unregister({0})", spu);
            // Return if nothing to unregister.
            if (!mLoadedSpuCache.ContainsKey(key))
            {
                return;
            }
            // Find instance of the signal processor.
            int instanceID = mLoadedSpuCache[key].FindIndex(x => x == spu);

            if (instanceID != -1)
            {
                // Remove satellite if no signal processors remain.
                if (mLoadedSpuCache[key].Count == 1)
                {
                    if (mSatelliteCache.ContainsKey(key))
                    {
                        VesselSatellite sat = mSatelliteCache[key];
                        OnUnregister(sat);
                        mSatelliteCache.Remove(key);
                    }
                    mLoadedSpuCache[key].RemoveAt(instanceID);
                    mLoadedSpuCache.Remove(key);

                    // search vessel by id
                    Vessel vessel = RTUtil.GetVesselById(key);
                    if (vessel != null)
                    {
                        // trigger the onRails on more time
                        // to reregister the satellite as a protoSat
                        this.OnVesselOnRails(vessel);
                    }
                }
                else
                {
                    mLoadedSpuCache[key].RemoveAt(instanceID);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Adds a new ground station to the list.
        /// </summary>
        /// <param name="name">Name of the ground station</param>
        /// <param name="latitude">Latitude position</param>
        /// <param name="longitude">Longitude position</param>
        /// <param name="height">Height above sea level</param>
        /// <param name="body">Reference body 1=Kerbin etc...</param>
        /// <returns>A new <see cref="Guid"/> if a new station was successfully added otherwise a Guid.Empty.</returns>
        public Guid AddGroundStation(string name, double latitude, double longitude, double height, int body)
        {
            RTLog.Notify("Trying to add ground station({0})", RTLogLevel.LVL1, name);

            var newGroundStation = new MissionControlSatellite();

            newGroundStation.SetDetails(name, latitude, longitude, height, body);

            // Already on the list?
            var foundGroundStation = GroundStations.FirstOrDefault(ms => ms.GetDetails().Equals(newGroundStation.GetDetails()));

            if (foundGroundStation != null)
            {
                RTLog.Notify("Ground station already exists!");
                return(Guid.Empty);
            }

            GroundStations.Add(newGroundStation);
            Save();

            return(newGroundStation.mGuid);
        }
Пример #8
0
        public static void AddSanctionedPilot(Guid id, Action <FlightCtrlState> autopilot)
        {
            var satellite = RTCore.Instance.Satellites[id];

            if (satellite == null)
            {
                return;
            }
            foreach (var spu in satellite.SignalProcessors)
            {
                if (spu.FlightComputer == null)
                {
                    continue;
                }
                if (spu.FlightComputer.SanctionedPilots.Contains(autopilot))
                {
                    continue;
                }
                RTLog.Verbose("Flight: {0} Adding Sanctioned Pilot", id);
                spu.FlightComputer.SanctionedPilots.Add(autopilot);
            }
        }
Пример #9
0
        public void Register(Guid key, IAntenna antenna)
        {
            RTLog.Notify("AntennaManager: Register({0})", antenna);

            if (!mLoadedAntennaCache.ContainsKey(key))
            {
                mLoadedAntennaCache[key] = new List <IAntenna>();
            }

            IAntenna instance = mLoadedAntennaCache[key].Find(a => a == antenna);

            if (instance == null)
            {
                if (mProtoAntennaCache.ContainsKey(key))
                {
                    UnregisterProtos(key);
                }

                mLoadedAntennaCache[key].Add(antenna);
                OnRegister.Invoke(antenna);
            }
        }
Пример #10
0
        private void AddTransmitter()
        {
            if (mTransmitterConfig == null || !mTransmitterConfig.HasValue("name"))
            {
                return;
            }
            var transmitters = part.FindModulesImplementing <IScienceDataTransmitter>();

            if (transmitters.Count > 0)
            {
                RTLog.Notify("ModuleRTAntenna: Find TRANSMITTER success.");
                mTransmitter = transmitters.First();
            }
            else
            {
                var copy = new ConfigNode();
                mTransmitterConfig.CopyTo(copy);
                part.AddModule(copy);
                AddTransmitter();
                RTLog.Notify("ModuleRTAntenna: Add TRANSMITTER success.");
            }
        }
Пример #11
0
        private static void SearchAndPreparePresets(Settings settings)
        {
            var presetsChanged = false;

            // Exploit KSP's GameDatabase to find third-party mods' RemoteTechSetting node (from GameData/ExampleMod/RemoteTechSettings.cfg)
            var cfgs          = GameDatabase.Instance.GetConfigs("RemoteTechSettings");
            var rtSettingCfGs = cfgs.Select(x => x.url).ToList();

            //check for any invalid preset in the settings of a save
            for (var i = 0; i < settings.PreSets.Count(); i++)
            {
                if (rtSettingCfGs.Contains(settings.PreSets[i]))
                {
                    continue;
                }

                RTLog.Notify("Remove an invalid setting preset {0}", settings.PreSets[i]);
                settings.PreSets.RemoveAt(i);
                presetsChanged = true;
            }

            //find and add new presets to the settings of a save
            for (var i = 0; i < rtSettingCfGs.Count(); i++)
            {
                if (settings.PreSets.Contains(rtSettingCfGs[i]))
                {
                    continue;
                }

                RTLog.Notify("Add a new setting preset {0}", rtSettingCfGs[i]);
                settings.PreSets.Add(rtSettingCfGs[i]);
                presetsChanged = true;
            }

            if (presetsChanged) // only if new RT settings are found and added to the save-setting's PreSets node
            {
                settings.Save();
            }
        }
Пример #12
0
        /// <summary>
        /// Saves the current RTSettings object to the RemoteTech_Settings.cfg
        /// </summary>
        public void Save()
        {
            try
            {
                // only save the settings if the file name is not empty (i.e. not on loading screen or in training)
                if (string.IsNullOrEmpty(SaveSettingFile))
                {
                    return;
                }

                var details = new ConfigNode("RemoteTechSettings");
                ConfigNode.CreateConfigFromObject(this, 0, details);
                var save = new ConfigNode();
                save.AddNode(details);
                save.Save(SaveSettingFile);

                RTSettings.OnSettingsSaved.Fire();
            }
            catch (Exception e)
            {
                RTLog.Notify("An error occurred while attempting to save: {0}", RTLogLevel.LVL1, e.Message);
            }
        }
Пример #13
0
        public void Start()
        {
            // Destroy the Core instance if != null or if Remotetech is disabled
            if (Instance != null || !RTSettings.Instance.RemoteTechEnabled)
            {
                Destroy(this);
                return;
            }

            Instance = this;

            ctrlLockAddon = new AddOns.ControlLockAddon();
            kacAddon      = new AddOns.KerbalAlarmClockAddon();

            Satellites = new SatelliteManager();
            Antennas   = new AntennaManager();
            Network    = new NetworkManager();
            Renderer   = NetworkRenderer.CreateAndAttach();

            FilterOverlay     = new FilterOverlay();
            FocusOverlay      = new FocusOverlay();
            TimeWarpDecorator = new TimeWarpDecorator();

            // Handling new F2 GUI Hiding
            GameEvents.onShowUI.Add(UIOn);
            GameEvents.onHideUI.Add(UIOff);

            FlightUIPatcher.Patch();

            RTLog.Notify("RTCore {0} loaded successfully.", RTUtil.Version);

            foreach (var vessel in FlightGlobals.Vessels)
            {
                Satellites.RegisterProto(vessel);
                Antennas.RegisterProtos(vessel);
            }
        }
Пример #14
0
        private List <IScalarModule> FindFxModules(int[] indices, bool showUI)
        {
            var modules = new List <IScalarModule>();

            if (indices == null)
            {
                return(modules);
            }
            foreach (int i in indices)
            {
                var item = base.part.Modules[i] as IScalarModule;
                if (item != null)
                {
                    item.SetUIWrite(showUI);
                    item.SetUIRead(showUI);
                    modules.Add(item);
                }
                else
                {
                    RTLog.Notify("ModuleRTAntenna: Part Module {0} doesn't implement IScalarModule", part.Modules[i].name);
                }
            }
            return(modules);
        }
Пример #15
0
        private IEnumerator Transmit()
        {
            var msg        = new ScreenMessage(String.Format("[{0}]: Starting Transmission...", part.partInfo.title), 4f, ScreenMessageStyle.UPPER_LEFT);
            var msg_status = new ScreenMessage(String.Empty, 4.0f, ScreenMessageStyle.UPPER_LEFT);

            ScreenMessages.PostScreenMessage(msg);

            mBusy = true;

            while (mQueue.Any())
            {
                RnDCommsStream commStream   = null;
                var            science_data = mQueue[0];
                var            data_amount  = science_data.dataAmount;
                mQueue.RemoveAt(0);
                var subject = ResearchAndDevelopment.GetSubjectByID(science_data.subjectID);
                int packets = Mathf.CeilToInt(science_data.dataAmount / PacketSize);
                if (ResearchAndDevelopment.Instance != null)
                {
                    // pre calculate the time interval - fix for x64 systems
                    // workaround for issue #136
                    float time1 = Time.time;
                    yield return(new WaitForSeconds(PacketInterval));

                    // get the delta time
                    float x64PacketInterval = (Time.time - time1);

                    RTLog.Notify("Changing RnDCommsStream timeout from {0} to {1}", PacketInterval, x64PacketInterval);

                    commStream = new RnDCommsStream(subject, science_data.dataAmount, x64PacketInterval,
                                                    science_data.transmitValue, ResearchAndDevelopment.Instance);
                }
                //StartCoroutine(SetFXModules_Coroutine(modules_progress, 0.0f));
                float power = 0;
                while (packets > 0)
                {
                    power += part.RequestResource("ElectricCharge", PacketResourceCost - power);
                    if (power >= PacketResourceCost * 0.95)
                    {
                        float frame = Math.Min(PacketSize, data_amount);
                        power       -= PacketResourceCost;
                        GUI_Status   = "Uploading Data...";
                        data_amount -= frame;
                        packets--;
                        float progress = (science_data.dataAmount - data_amount) / science_data.dataAmount;
                        //StartCoroutine(SetFXModules_Coroutine(modules_progress, progress));
                        msg_status.message = String.Format("[{0}]: Uploading Data... {1}", part.partInfo.title, progress.ToString("P0"));
                        RTLog.Notify("[Transmitter]: Uploading Data... ({0}) - {1} Mits/sec. Packets to go: {2} - Files to Go: {3}",
                                     science_data.title, (PacketSize / PacketInterval).ToString("0.00"), packets, mQueue.Count);
                        ScreenMessages.PostScreenMessage(msg_status, true);
                        if (commStream != null)
                        {
                            commStream.StreamData(frame);
                        }
                    }
                    else
                    {
                        msg.message = String.Format("<b><color=orange>[{0}]: Warning! Not Enough {1}!</color></b>", part.partInfo.title, RequiredResource);
                        ScreenMessages.PostScreenMessage(msg, true);
                        GUI_Status = String.Format("{0}/{1} {2}", power, PacketResourceCost, RequiredResource);
                    }
                    yield return(new WaitForSeconds(PacketInterval));
                }
                yield return(new WaitForSeconds(PacketInterval * 2));
            }
            mBusy       = false;
            msg.message = String.Format("[{0}]: Done!", part.partInfo.title);
            ScreenMessages.PostScreenMessage(msg, true);
            GUI_Status = "Idle";
            yield break;
        }
Пример #16
0
 private void OnVesselDestroy(Vessel v)
 {
     RTLog.Notify("SatelliteManager: OnVesselDestroy({0}, {1})", v.id, v.vesselName);
     UnregisterProto(v.id);
 }
Пример #17
0
        public static Settings Load()
        {
            // Create a new settings object
            Settings settings = new Settings();

            // Disable RemoteTech on Training missions
            if (RTUtil.IsGameScenario)
            {
                settings.RemoteTechEnabled = false;
            }

            // skip loading if we are on the loading screen
            // and return the default object and also for
            // scenario games.
            if (string.IsNullOrEmpty(Settings.File))
            {
                return(settings);
            }

            settings.settingsLoaded = true;

            // try to load from the base settings.cfg
            ConfigNode load = ConfigNode.Load(Settings.File);

            if (load == null)
            {
                // write new base file to the rt folder
                settings.Save();
                settings.firstStart = true;
            }
            else
            {
                // old or new format?
                if (load.HasNode("RemoteTechSettings"))
                {
                    load = load.GetNode("RemoteTechSettings");
                }
                RTLog.Notify("Load base settings into object with {0}", load);
                // load basic file
                ConfigNode.LoadObjectFromConfig(settings, load);
            }

            bool presetsLoaded = false;

            // Prefer to load from GameDatabase, to allow easier user customization
            UrlDir.UrlConfig[] configList = GameDatabase.Instance.GetConfigs("RemoteTechSettings");
            // find the default_settings from remote tech to load as the first settings
            UrlDir.UrlConfig defConfig = Array.Find(configList, cl => cl.url.Equals("RemoteTech/Default_Settings/RemoteTechSettings") && !settings.PreSets.Contains(cl.url));
            if (defConfig != null)
            {
                RTLog.Notify("Load default remotetech settings", RTLogLevel.LVL1);
                settings = Settings.LoadPreset(settings, defConfig);
            }

            foreach (UrlDir.UrlConfig curSet in configList)
            {
                // only third party files
                if (!curSet.url.Equals("RemoteTech/RemoteTech_Settings/RemoteTechSettings") && !settings.PreSets.Contains(curSet.url))
                {
                    settings = Settings.LoadPreset(settings, curSet);
                    // trigger to save the settings again
                    presetsLoaded = true;
                }
            }

            if (presetsLoaded)
            {
                settings.Save();
            }
            RTSettings.OnSettingsLoaded.Fire();

            return(settings);
        }
Пример #18
0
 private void OnVesselCreate(Vessel v)
 {
     RTLog.Notify("SatelliteManager: OnVesselCreate({0}, {1})", v.id, v.vesselName);
 }
Пример #19
0
 private void OnSatelliteRegister(ISatellite s)
 {
     RTLog.Notify("NetworkManager: SatelliteRegister({0})", s);
     Graph[s.Guid] = new List <NetworkLink <ISatellite> >();
 }
Пример #20
0
        /// <summary>
        /// Utilise KSP's GameDatabase to get a list of cfgs, included our Default_Settings.cfg, contained the 'RemoteTechSettings'
        /// node and process each cfg accordingly
        ///
        /// NOTE: Please do not use the static 'Default_Settings.cfg' file directly because we want third-party modders to apply
        /// ModuleManager patches of their tweaks, like no signal delay, to our default-settings cfg that will be used when a
        /// player starts a new game. (refer to our online manual for more details)
        /// </summary>
        public static Settings Load()
        {
            // Create a blank object of settings
            var settings       = new Settings();
            var defaultSuccess = false;

            // Exploit KSP's GameDatabase to find our MM-patched cfg of default settings (from GameData/RemoteTech/Default_Settings.cfg)
            var cfgs = GameDatabase.Instance.GetConfigs("RemoteTechSettings");

            for (var i = 0; i < cfgs.Length; i++)
            {
                if (cfgs[i].url.Equals(DefaultSettingCfgURL))
                {
                    defaultSuccess = ConfigNode.LoadObjectFromConfig(settings, cfgs[i].config);
                    RTLog.Notify("Load default settings into object with {0}: LOADED {1}", cfgs[i].config, defaultSuccess ? "OK" : "FAIL");
                    break;
                }
            }

            if (!defaultSuccess) // disable itself and write explanation to KSP's log
            {
                RTLog.Notify("RemoteTech is disabled because the default cfg '{0}' is not found", DefaultSettingCfgURL);
                return(null);
                // the main impact of returning null is the endless loop of invoking Load() in the KSP's loading screen
            }

            settings.SettingsLoaded = true;

            // Disable RemoteTech on Training missions
            if (RTUtil.IsGameScenario)
            {
                settings.RemoteTechEnabled = false;
                settings.CommNetEnabled    = true;
            }

            // stop and return default settings if we are on the KSP loading screen OR in training scenarios
            if (string.IsNullOrEmpty(SaveSettingFile))
            {
                return(settings);
            }

            // try to load from the save-settings.cfg (MM-patches will not touch because it is outside GameData)
            var load = ConfigNode.Load(SaveSettingFile);

            if (load == null)
            {
                // write the RT settings to the player's save folder
                settings.Save();
                settings.FirstStart = true;
            }
            else
            {
                // old or new format?
                if (load.HasNode("RemoteTechSettings"))
                {
                    load = load.GetNode("RemoteTechSettings");
                }

                // replace the default settings with save-setting file
                var success = ConfigNode.LoadObjectFromConfig(settings, load);
                RTLog.Notify("Found and load save settings into object with {0}: LOADED {1}", load, success ? "OK" : "FAIL");
            }

            // find third-party mods' RemoteTech settings
            SearchAndPreparePresets(settings);

            RTSettings.OnSettingsLoaded.Fire();

            return(settings);
        }
Пример #21
0
        /// <summary>
        /// Utilise KSP's GameDatabase to get a list of cfgs, included our Default_Settings.cfg, contained the 'RemoteTechSettings'
        /// node and process each cfg accordingly
        ///
        /// NOTE: Please do not use the static 'Default_Settings.cfg' file directly because we want third-party modders to apply
        /// ModuleManager patches of their tweaks, like no signal delay, to our default-settings cfg that will be used when a
        /// player starts a new game. (refer to our online manual for more details)
        /// </summary>
        public static Settings Load()
        {
            // Create a blank object of settings
            var settings       = new Settings();
            var defaultSuccess = false;

            // Exploit KSP's GameDatabase to find our MM-patched cfg of default settings (from GameData/RemoteTech/Default_Settings.cfg)
            var cfgs = GameDatabase.Instance.GetConfigs("RemoteTechSettings");

            for (var i = 0; i < cfgs.Length; i++)
            {
                if (cfgs[i].url.Equals(DefaultSettingCfgURL))
                {
                    defaultSuccess = ConfigNode.LoadObjectFromConfig(settings, cfgs[i].config);
                    RTLog.Notify("Load default settings into object with {0}: LOADED {1}", cfgs[i].config, defaultSuccess ? "OK" : "FAIL");
                    break;
                }
            }

            if (!defaultSuccess) // disable itself and write explanation to KSP's log
            {
                RTLog.Notify("RemoteTech is disabled because the default cfg '{0}' is not found", DefaultSettingCfgURL);
                return(null);
                // the main impact of returning null is the endless loop of invoking Load() in the KSP's loading screen
            }

            settings.SettingsLoaded = true;

            // Disable RemoteTech on Training missions
            if (RTUtil.IsGameScenario)
            {
                settings.RemoteTechEnabled = false;
                settings.CommNetEnabled    = true;
            }

            // stop and return default settings if we are on the KSP loading screen OR in training scenarios
            if (string.IsNullOrEmpty(SaveSettingFile))
            {
                return(settings);
            }

            // try to load from the save-settings.cfg (MM-patches will not touch because it is outside GameData)
            var load = ConfigNode.Load(SaveSettingFile);

            if (load == null)
            {
                // write the RT settings to the player's save folder
                settings.Save();
                settings.FirstStart = true;
            }
            else
            {
                // old or new format?
                if (load.HasNode("RemoteTechSettings"))
                {
                    load = load.GetNode("RemoteTechSettings");
                }

                // replace the default settings with save-setting file
                var success = ConfigNode.LoadObjectFromConfig(settings, load);
                RTLog.Notify("Found and load save settings into object with {0}: LOADED {1}", load, success ? "OK" : "FAIL");
            }

            // find third-party mods' RemoteTech settings
            SearchAndPreparePresets(settings);

            // Detect if the celestial body, that Mission Control is on (default body index 1), is Kerbin
            var KSCMC = settings.GroundStations.Find(x => x.GetName().Equals("Mission Control"));                   // leave extra ground stations to modders, who need to provide MM patches

            if (KSCMC != null && !KSCMC.GetBody().name.Equals("Kerbin") && KSCMC.GetBody().flightGlobalsIndex == 1) // Kopernicus or similar map changes the planet
            {
                KSCMC.SetBodyIndex(FlightGlobals.GetHomeBodyIndex());
                RTLog.Notify("KSC's Mission Control is on the wrong planet (not Kerbin/Earth) (Any Kopernicus/similar map would change). Relocated to the homeworld's body index {0}.", FlightGlobals.GetHomeBodyIndex());
            }

            RTSettings.OnSettingsLoaded.Fire();

            return(settings);
        }