protected void SetOrbit() { OrbitSnapshot protoOrbit = orbitProtoVessel.orbitSnapShot; int selBodyIndex = protoOrbit.ReferenceBodyIndex; double sma = protoOrbit.semiMajorAxis; double ecc = protoOrbit.eccentricity; double inc = protoOrbit.inclination; double LAN = protoOrbit.LAN; double mna = protoOrbit.meanAnomalyAtEpoch; double argPe = protoOrbit.argOfPeriapsis; double epoch = protoOrbit.epoch; Debug.Log( string.Format("[BeenThereDoneThat]: RESTORING ORBIT> sma: {0} ecc: {1} inc: {2} LAN: {3} mna: {4} argPe: {5} epoch: {6}", sma, ecc, inc, LAN, mna, argPe, epoch)); // hackishly temporarily set planetarium time double prevTime = Planetarium.fetch.time; Planetarium.fetch.time = epoch; FlightGlobals.fetch.SetShipOrbit(selBodyIndex, ecc, sma, inc, LAN, argPe, mna, 0); // hackishly restore planetarium time Planetarium.fetch.time = prevTime; Debug.Log("[BeenThereDoneThat]: Put ship into orbit"); }
virtual public void Load(ConfigNode node) { try { ConfigNode.LoadObjectFromConfig(this, node); } catch (Exception e) { Utils.Log("Exception while loading {}\n{}\n{}\n{}", this, e.Message, e.StackTrace, node); } foreach (var fi in get_fields()) { if (not_persistant(fi)) { continue; } var n = node.GetNode(fi.Name); //restore types saved as nodes if (n != null) { //restore IConfigNodes if (fi.FieldType.GetInterface(cnode_name) != null) { var f = get_or_create <IConfigNode>(fi); if (f != null) { f.Load(n); fi.SetValue(this, f); } } //restore ConfigNodes else if (typeof(ConfigNode).IsAssignableFrom(fi.FieldType)) { fi.SetValue(this, n.CreateCopy()); } //restore Orbit else if (fi.FieldType == typeof(Orbit)) { var obt = new OrbitSnapshot(n); fi.SetValue(this, obt.Load()); } continue; } //restore types saved as values var v = node.GetValue(fi.Name); if (v != null) { if (fi.FieldType == typeof(Guid)) { fi.SetValue(this, new Guid(v)); } else if (fi.FieldType == typeof(Vector3d)) { fi.SetValue(this, KSPUtil.ParseVector3d(v)); } } } }
static ConfigNode orbit(Orbit orb) { var snap = new OrbitSnapshot(orb); var node = new ConfigNode(); snap.Save(node); return(node); }
virtual public void Save(ConfigNode node) { try { ConfigNode.CreateConfigFromObject(this, node); } catch (Exception e) { Utils.Log("Exception while saving {}\n{}\n{}\n{}", GetType().Name, e.Message, e.StackTrace, node); } foreach (var fi in get_fields()) { if (not_persistant(fi)) { continue; } //save all IConfigNode if (fi.FieldType.GetInterface(cnode_name) != null) { var f = fi.GetValue(this) as IConfigNode; if (f != null) { f.Save(get_field_node(fi, node)); } } //save ConfigNode else if (typeof(ConfigNode).IsAssignableFrom(fi.FieldType)) { var f = fi.GetValue(this) as ConfigNode; if (f != null) { get_field_node(fi, node).AddData(f); } } //save some often used types else if (fi.FieldType == typeof(Guid)) { node.AddValue(fi.Name, ((Guid)fi.GetValue(this)).ToString("N")); } else if (fi.FieldType == typeof(Vector3d)) { node.AddValue(fi.Name, KSPUtil.WriteVector((Vector3d)fi.GetValue(this))); } else if (fi.FieldType == typeof(Orbit)) { var f = fi.GetValue(this) as Orbit; if (f != null) { var obt = new OrbitSnapshot(f); obt.Save(get_field_node(fi, node)); } } } }
public override bool isVesselAtPoint(Vessel v) { if (v.loaded) { Orbit curOrbit = v.GetOrbit(); if (curOrbit.referenceBody != soi) { return(false); } if ( // TODO: tweak these thresholds (Math.Abs(curOrbit.eccentricity - ecc) < 0.05) && // Allowed eccentricity variance is +- 0.05. (Math.Abs(curOrbit.semiMajorAxis - sma) < 10000.0) && // Allowed SMA variance is +- 10km. (Math.Abs(curOrbit.inclination - inc) < 5) // Allowed inclination variance is +- 5 degrees ) { return(true); } } else { OrbitSnapshot curOrbit = v.protoVessel.orbitSnapShot; if (FlightGlobals.Bodies[curOrbit.ReferenceBodyIndex] != soi) { return(false); } if ( // TODO: tweak these thresholds (Math.Abs(curOrbit.eccentricity - ecc) < 0.05) && // Allowed eccentricity variance is +- 0.05. (Math.Abs(curOrbit.semiMajorAxis - sma) < 10000.0) && // Allowed SMA variance is +- 10km. (Math.Abs(curOrbit.inclination - inc) < 5) // Allowed inclination variance is +- 5 degrees ) { return(true); } } return(false); }
public override void moveVesselToPoint(Vessel v) { CelestialBody oldSOI = v.GetOrbitDriver().orbit.referenceBody; /* Update driven orbit so the rest of KSP knows: */ Orbit orb = v.GetOrbitDriver().orbit; orb.inclination = inc; orb.eccentricity = ecc; orb.semiMajorAxis = sma; orb.LAN = lan; orb.argumentOfPeriapsis = argP; orb.meanAnomalyAtEpoch = 0; orb.referenceBody = soi; orb.Init(); orb.UpdateFromUT(Planetarium.GetUniversalTime()); /* Update the saved orbit so the rest of our code knows: */ OrbitSnapshot orbSnap = v.protoVessel.orbitSnapShot; orbSnap.inclination = inc; orbSnap.eccentricity = ecc; orbSnap.semiMajorAxis = sma; orbSnap.LAN = lan; orbSnap.argOfPeriapsis = argP; orbSnap.meanAnomalyAtEpoch = 0; orbSnap.ReferenceBodyIndex = soi.flightGlobalsIndex; if (oldSOI != soi) { GameEvents.onVesselSOIChanged.Fire( new GameEvents.HostedFromToAction <Vessel, CelestialBody>(v, oldSOI, soi) ); } }
static ConfigNode orbit (Orbit orb) { var snap = new OrbitSnapshot (orb); var node = new ConfigNode (); snap.Save (node); return node; }
private System.Collections.IEnumerator UpdateObservers() { while (true) { if (!FlightGlobals.ready || FlightGlobals.ActiveVessel == null) { yield return(0); continue; } var expSituation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel); foreach (var observer in observers) { try { #if PROFILE float start = Time.realtimeSinceStartup; #endif bool newReport = false; // Is exciting new research available? if (observer.UpdateStatus(expSituation, out newReport)) { // if we're timewarping, resume normal time if that setting was used if (observer.StopWarpOnDiscovery || Settings.Instance.GlobalWarp == Settings.WarpSetting.GlobalOn) { if (Settings.Instance.GlobalWarp != Settings.WarpSetting.GlobalOff) { if (TimeWarp.CurrentRateIndex > 0) { OrbitSnapshot snap = new OrbitSnapshot(FlightGlobals.ActiveVessel.GetOrbitDriver().orbit); TimeWarp.SetRate(0, true); FlightGlobals.ActiveVessel.GetOrbitDriver().orbit = snap.Load(); FlightGlobals.ActiveVessel.GetOrbitDriver().orbit.UpdateFromUT(Planetarium.GetUniversalTime()); } } } scienceAlert.Button.Important = true; if (observer.settings.AnimationOnDiscovery) { scienceAlert.Button.PlayAnimation(); } else if (scienceAlert.Button.IsNormal) { scienceAlert.Button.SetLit(); } switch (Settings.Instance.SoundNotification) { case Settings.SoundNotifySetting.ByExperiment: if (observer.settings.SoundOnDiscovery) { audio.PlayUI("bubbles", 2f); } break; case Settings.SoundNotifySetting.Always: audio.PlayUI("bubbles", 2f); break; } OnExperimentAvailable(observer.Experiment, observer.NextReportValue); } else if (!observers.Any(ob => ob.Available)) { scienceAlert.Button.SetUnlit(); scienceAlert.Button.Important = false; } #if PROFILE Log.Warning("Tick time ({1}): {0} ms", (Time.realtimeSinceStartup - start) * 1000f, observer.ExperimentTitle); #endif } catch (Exception e) { Log.Debug("ExperimentManager.UpdateObservers: exception {0}", e); } if (TimeWarp.CurrentRate < Settings.Instance.TimeWarpCheckThreshold) { yield return(0); // pause until next frame } } // end observer loop yield return(0); } // end infinite while loop }
/// <summary> /// Update state of all experiment observers. If their status has /// changed, UpdateStatus will return true. /// </summary> /// <returns></returns> private System.Collections.IEnumerator UpdateObservers() { while (true) { if (!FlightGlobals.ready || FlightGlobals.ActiveVessel == null) { yield return(0); continue; } // if any new experiments become available, our state // changes (remember: observers return true only if their observed // experiment wasn't available before and just become available this update) var expSituation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel); foreach (var observer in observers) { try { #if PROFILE float start = Time.realtimeSinceStartup; #endif bool newReport = false; // Is exciting new research available? if (observer.UpdateStatus(expSituation, out newReport)) { // if we're timewarping, resume normal time if that setting // was used if (observer.StopWarpOnDiscovery || Settings.Instance.GlobalWarp == Settings.WarpSetting.GlobalOn) { if (Settings.Instance.GlobalWarp != Settings.WarpSetting.GlobalOff) { if (TimeWarp.CurrentRateIndex > 0) { // Simply setting warp index to zero causes some kind of // accuracy problem that can seriously affect the // orbit of the vessel. // // to avoid this, we'll take a snapshot of the orbit // pre-warp and then apply it again after we've changed // the warp rate OrbitSnapshot snap = new OrbitSnapshot(FlightGlobals.ActiveVessel.GetOrbitDriver().orbit); TimeWarp.SetRate(0, true); FlightGlobals.ActiveVessel.GetOrbitDriver().orbit = snap.Load(); FlightGlobals.ActiveVessel.GetOrbitDriver().orbit.UpdateFromUT(Planetarium.GetUniversalTime()); } } } // the button is important; if it's auto-hidden we should // show it to the player scienceAlert.Button.Important = true; if (observer.settings.AnimationOnDiscovery) { scienceAlert.Button.PlayAnimation(); } else if (scienceAlert.Button.IsNormal) { scienceAlert.Button.SetLit(); } switch (Settings.Instance.SoundNotification) { case Settings.SoundNotifySetting.ByExperiment: if (observer.settings.SoundOnDiscovery) { audio.PlayUI("bubbles", 2f); } break; case Settings.SoundNotifySetting.Always: audio.PlayUI("bubbles", 2f); break; } OnExperimentAvailable(observer.Experiment, observer.NextReportValue); } else if (!observers.Any(ob => ob.Available)) { // if no experiments are available, we should be looking // at a starless flask in the menu. Note that this is // in an else statement because if UpdateStatus just // returned true, we know there's at least one experiment // available this frame //Log.Debug("No observers available: resetting state"); scienceAlert.Button.SetUnlit(); scienceAlert.Button.Important = false; } #if PROFILE Log.Warning("Tick time ({1}): {0} ms", (Time.realtimeSinceStartup - start) * 1000f, observer.ExperimentTitle); #endif } catch (Exception e) { Log.Debug("ExperimentManager.UpdateObservers: exception {0}", e); } // if the user accelerated time it's possible to have some // experiments checked too late. If the user is time warping // quickly enough, then we'll go ahead and check every // experiment on every loop if (TimeWarp.CurrentRate < Settings.Instance.TimeWarpCheckThreshold) { yield return(0); // pause until next frame } } // end observer loop yield return(0); } // end infinite while loop }