Beispiel #1
0
        public override void Draw(Unity.Flight.ISectionModule section)
        {
            var biome = ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude);

            biome = ScienceUtil.GetBiomedisplayName(FlightGlobals.ActiveVessel.mainBody, biome);
            this.DrawLine(biome, section.IsHud);
        }
        public override string ToString()
        {
            if (biome == "KSC")
            {
                return(ScienceUtil.GetBiomedisplayName(body, biome));
            }

            return(Localizer.Format("#cc.science.biomeIdentifier", (body == null ? "" : IsKSC() ? Localizer.GetStringByTag("#autoLOC_300900") : body.displayName), ScienceUtil.GetBiomedisplayName(body, biome)));
        }
Beispiel #3
0
 protected override string GetSynopsys()
 {
     if (biome != "")
     {
         string biomedisplayName = ScienceUtil.GetBiomedisplayName(target, biome);
         return(Localizer.Format("#autoLOC_TST_0056", biomedisplayName, target.displayName)); //#autoLOC_TST_0056 = Use the ChemCam to analyse the surface composition of the <<1>> on <<2>>
     }
     return(Localizer.Format("#autoLOC_TST_0057", target.displayName));                       //#autoLOC_TST_0057 = Use the ChemCam to analyse the surface of <<1>>
 }
Beispiel #4
0
        internal void FinalizeExperiment()
        {
            Log.Info("FinalizeExperiment");

            ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(activeExperiment.activeExpid);


            string displayBiome = "";

            if (vessel.landedAt != string.Empty)
            {
                activeExperiment.biomeSit = Vessel.GetLandedAtString(vessel.landedAt);
                displayBiome = Localizer.Format(vessel.displaylandedAt);
            }
            else
            {
                activeExperiment.biomeSit = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, activeExperiment.biomeSit);
            }

            ModuleScienceExperiment exp = activeExperiment.mse;

#if DEBUG
            var step = "Get Subject";
#endif
            ScienceSubject labSub = ResearchAndDevelopment.GetExperimentSubject(labExp, activeExperiment.expSit, vessel.mainBody, activeExperiment.biomeSit, displayBiome);
            labSub.title         = $"{labExp.experimentTitle}";
            labSub.subjectValue *= labBoostScalar;
            labSub.scienceCap    = labExp.scienceCap * labSub.subjectValue;

#if DEBUG
            step = "Calculate Points";
#endif
            float sciencePoints = labExp.baseValue * labExp.dataScale;

            ScienceData labData = new ScienceData(sciencePoints, exp.xmitDataScalar, 0, labSub.id, labSub.title, false, vessel.rootPart.flightID);

#if DEBUG
            step = "Add Experiment";
#endif
            _storedData.Add(labData);

#if DEBUG
            step = "Show Dialog";
#endif
            Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_238419", vessel.rootPart.partInfo.title, labData.dataAmount, labSub.title));
            ReviewDataItem(labData);

            expStatuses.Remove(activeExperiment.Key);
            activeExperiment = null;
        }
        public void doScience(CelestialBody planet)
        {
            Utilities.Log_Debug("Doing Science for {0}", planet.name);
            ScienceExperiment experiment = ResearchAndDevelopment.GetExperiment(ExperimentID);

            Utilities.Log_Debug("Got experiment");
            ExperimentSituations situation = ScienceUtil.GetExperimentSituation(vessel);

            if (experiment.IsAvailableWhile(ScienceUtil.GetExperimentSituation(vessel), planet))
            {
                string biomeID        = "";
                string displaybiomeID = string.Empty;
                if (part.vessel.landedAt != string.Empty)
                {
                    biomeID        = Vessel.GetLandedAtString(part.vessel.landedAt);
                    displaybiomeID = Localizer.Format(part.vessel.displaylandedAt);
                }
                else
                {
                    biomeID        = ScienceUtil.GetExperimentBiome(planet, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude);
                    displaybiomeID = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biomeID);
                }
                ScienceSubject subject = ResearchAndDevelopment.GetExperimentSubject(experiment, situation, planet, biomeID, displaybiomeID);
                Utilities.Log_Debug("Got subject");
                ScienceData data = new ScienceData(experiment.baseValue * subject.dataScale, xmitDataScalar, labBoostScalar, subject.id, subject.title, false, part.flightID);
                Utilities.Log_Debug("Got data");
                _scienceData.Add(data);
                Utilities.Log_Debug("Added Data");
                ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238419", part.partInfo.title, data.dataAmount.ToString(), subject.title), 8f, ScreenMessageStyle.UPPER_LEFT);
                ReviewDataItem(data);
                if (TSTProgressTracker.isActive)
                {
                    TSTProgressTracker.OnChemCamFire(planet, biomeID);
                }
            }
            else
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#autoLOC_238424", experiment.experimentTitle), 5f, ScreenMessageStyle.UPPER_CENTER);
            }
            updateAvailableEvents();
        }
        public void Update()
        {
            if (FlightEngineerCore.gamePaused)
            {
                return;
            }

            Vector3d futurepos = new Vector3d();
            var      body      = FlightGlobals.ActiveVessel.mainBody;
            var      vessel    = FlightGlobals.ActiveVessel;

            double terrainAltitude = 0;
            bool   impactHappening = false;
            double impactLatitude  = 0;
            double impactLongitude = 0;
            double impactTime      = 0;
            double impacttheta     = 0;

            SuicideAltitude  = 0;
            SuicideCountdown = 0;
            SuicideDeltaV    = 0;
            SuicideDistance  = 0;
            SuicideLength    = 0;
            ShowDetails      = false;

            bool debugImpact = false;

            if (vessel.Landed || body.pqsController == null)
            {
                return;
            }

            if (vessel.orbit.PeA >= body.minOrbitalDistance)
            {
                //periapsis must be lower min dist;
                if (debugImpact)
                {
                    Debug.Log("no impact: periapse > min alt " + vessel.orbit.PeA + body.minOrbitalDistance);
                }
                return;
            }

            if ((vessel.orbit.eccentricity >= 1) && (vessel.orbit.timeToPe <= 0))
            {
                //if currently escaping, we still need to be before periapsis
                if (debugImpact)
                {
                    Debug.Log("no impact: escaping and passed periapse");
                }
                return;
            }

            //if ((vessel.orbit.eccentricity < 1) && (vessel.orbit.ApA <= impactAltitude)) {
            //    //apoapsis must be higher than impact alt
            //    impactHappening = false;
            //    Debug.Log("no impact: ap < alt " + impactAltitude + " " + vessel.orbit.ApA);
            //}

            //do impact site calculations
            impactHappening = false;
            impactTime      = 0;
            impactLongitude = 0;
            impactLatitude  = 0;
            terrainAltitude = 0;

            var e = vessel.orbit.eccentricity;
            var a = vessel.orbit.semiMajorAxis;
            var r = body.Radius * 0.9999; //avoid floating point errors.

            //get current position direction vector
            var currentpos = vessel.orbit.getRelativePositionFromTrueAnomaly(vessel.orbit.trueAnomaly); // this.RadiusDirection(vessel.orbit.trueAnomaly * Units.RAD_TO_DEG);
            //calculate longitude in inertial reference frame from that
            var currentirflong = 180 * Math.Atan2(currentpos.x, currentpos.y) / Math.PI;

            int side = 1;

            double startangle = vessel.GetOrbit().trueAnomaly * 180 / Math.PI;

            if (startangle > 0)
            {
                startangle = -360 + startangle;
            }

            double endangle = startangle + 360;

            if (vessel.orbit.PeR <= body.Radius)   //only search down to sea level.
            {
                double costheta = a / r / e - a * e / r - 1 / e;

                if (costheta < -1d)
                {
                    costheta = -1d;
                }
                else if (costheta > 1d)
                {
                    costheta = 1d;
                }

                endangle  = -180 * Math.Acos(costheta) / Math.PI;
                endangle += Math.Abs(endangle - startangle) / 10; //avoid errors at 0;
            }

            //} else if (vessel.orbit.PeR <= body.minOrbitalDistance && vessel.orbit.ApR > body.minOrbitalDistance) {
            //    //search to min dist exit.
            //    r = body.minOrbitalDistance;
            //    double costheta = a / r * e - a * e / r - 1 / e;
            //    if (costheta < -1d)
            //        costheta = -1d;
            //    else if (costheta > 1d)
            //        costheta = 1d;
            //    endangle = -180 * Math.Acos(costheta) / Math.PI;

            //    if (vessel.orbit.timeToPe < 0) {
            //        if (endangle < 0) endangle *= -1;
            //    }

            //} else { //search all the way around. ap and pe both below min dist.
            //    endangle = startangle + 360;
            //}

            double interval = Math.Abs(endangle - startangle) / 36;
            int    it       = 0;
            int    itf      = 0;

            if (debugImpact)
            {
                Debug.Log("Impact pre " + side + " " + startangle + ">" + endangle + " " + interval + " " + terrainAltitude);
            }
            bool ok = false;

            do
            {
                ok  = false;
                it += 1;
                //-164 + 1.8*-1 ; -165 > -147
                for (impacttheta = startangle + interval * side; side == 1 ? impacttheta <= endangle : impacttheta >= endangle; impacttheta += interval * side)
                {
                    itf += 1;
                    double tARads = Math.PI * impacttheta / 180;
                    futurepos = vessel.orbit.getRelativePositionFromTrueAnomaly(tARads); //this.RadiusDirection(impacttheta);

                    if (futurepos.magnitude > body.minOrbitalDistance)
                    {
                        continue;
                    }

                    //calculate time to impact
                    impactTime = vessel.orbit.GetDTforTrueAnomaly(tARads, 0);
                    //calculate position vector of impact site
                    futurepos = vessel.orbit.getRelativePositionFromTrueAnomaly(tARads); //this.RadiusDirection(impacttheta);
                    //calculate longitude of impact site in inertial reference frame
                    var impactirflong = 180 * Math.Atan2(futurepos.x, futurepos.y) / Math.PI;
                    var deltairflong  = impactirflong - currentirflong;
                    //get body rotation until impact
                    var bodyrot = 360 * impactTime / body.rotationPeriod;
                    //get current longitude in body coordinates
                    var currentlong = vessel.longitude;
                    //finally, calculate the impact longitude in body coordinates
                    impactLongitude = this.NormAngle(currentlong - deltairflong - bodyrot);
                    //calculate impact latitude from impact position
                    impactLatitude = 180 * Math.Asin(futurepos.z / futurepos.magnitude) / Math.PI;
                    //calculate the actual altitude of the impact site
                    //altitude for long/lat code stolen from some ISA MapSat forum post; who knows why this works, but it seems to.
                    var rad = QuaternionD.AngleAxis(impactLongitude, Vector3d.down) * QuaternionD.AngleAxis(impactLatitude, Vector3d.forward) * Vector3d.right;
                    terrainAltitude = body.pqsController.GetSurfaceHeight(rad) - body.pqsController.radius;

                    double shipalt = futurepos.magnitude - body.Radius;

                    if ((terrainAltitude < 0) && body.ocean)
                    {
                        terrainAltitude = 0; //sploosh.
                    }

                    double delta = shipalt - terrainAltitude;

                    if (debugImpact)
                    {
                        Debug.Log("Impact iteration " + currentpos + " " + futurepos + " " + side + " " + startangle + ">" + endangle + " " + impacttheta + " " + interval + " " + shipalt + " " + terrainAltitude + " " + delta);
                    }

                    if ((side * delta < 0))
                    {
                        impactHappening = true;
                        side           *= -1;
                        startangle      = impacttheta;
                        endangle        = impacttheta + side * interval;
                        interval        = Math.Abs(endangle - startangle) / 20.0;
                        endangle       += interval * side;
                        if (debugImpact)
                        {
                            Debug.Log("Impact Switch! " + startangle + " > " + endangle + " " + interval);
                        }
                        ok = true;
                        break;
                    }
                    else if (delta == 0)     //i guess it could happen.
                    {
                        if (debugImpact)
                        {
                            Debug.Log("Impact Zero! " + startangle + " > " + endangle + " " + interval);
                        }
                        impactHappening = true;
                        interval        = 0;
                        ok = true;
                        break;
                    }
                }

                if (!ok)
                {
                    if (debugImpact)
                    {
                        Debug.Log("bad loop");
                    }
                    break;
                }
            } while (interval > 0.00001 && impactHappening && it < 36);

            if (debugImpact)
            {
                Debug.Log("Impact calc! iterations " + impactHappening + " " + it + " " + itf);
            }

            if (impactHappening)
            {
                ShowDetails = true;
                Time        = impactTime;
                Longitude   = impactLongitude;
                Latitude    = impactLatitude;
                Altitude    = terrainAltitude;

                try {
                    Biome = ScienceUtil.GetExperimentBiome(body, impactLatitude, impactLongitude);
                    Biome = ScienceUtil.GetBiomedisplayName(body, Biome);
                } catch (Exception ex) { //this gets spammy with misbehaving mod planets.
                    Biome = "<failed>";
                }

                double m_Gravity      = body.gravParameter / Math.Pow(body.Radius + terrainAltitude, 2.0);
                double m_Acceleration = Vessel.SimulationProcessor.LastStage.totalMass > 0 ? Vessel.SimulationProcessor.LastStage.thrust / Vessel.SimulationProcessor.LastStage.totalMass : 0;

                bool debugBurn = false;

                if (m_Acceleration == 0 || m_Acceleration < m_Gravity)
                {
                    //lol u dead, boy
                    if (debugBurn)
                    {
                        Debug.Log("insuffucuent thrust " + m_Acceleration);
                    }
                    return;
                }

                double   brakingDist = 0;
                double   burnTime    = 0;
                Vector3d srfb        = new Vector3d();
                double   shipalt     = 0;

                brakingDist = getBrakingDistanceForDT(vessel, 0, body, out shipalt, out burnTime, out srfb, false);
                //get instant breaking dist as sanity check.

                int iterations = 0;

                if (brakingDist < shipalt)   //only search if it's actually possible to stop.
                {
                    double   tstart     = 0;
                    double   tend       = Time;
                    double   lastt      = 0;
                    double   brakedelta = double.MaxValue;
                    double   btime      = 0;
                    Vector3d srf        = new Vector3d();
                    double   bdist      = 0;

                    do   //dat binary search doe. Is there a closed form solution to this? idk. brute force!
                    {
                        iterations++;
                        double t = tstart + (tend - tstart) / 2;

                        if (Math.Abs(lastt - t) < 0.05)
                        {
                            if (debugBurn)
                            {
                                getBrakingDistanceForDT(vessel, lastt, body, out shipalt, out btime, out srf, true);
                            }
                            break; //that should be quite enough, tyvm.
                        }

                        lastt = t;

                        bdist = getBrakingDistanceForDT(vessel, t, body, out shipalt, out btime, out srf, false);

                        if (bdist <= shipalt)
                        {
                            if (shipalt - bdist < brakedelta)
                            {
                                brakedelta  = shipalt - bdist;
                                brakingDist = bdist;
                                burnTime    = btime;
                                srfb        = srf;
                            }
                            tstart = t; //search forward.
                            if (debugBurn)
                            {
                                Debug.Log("forward: t " + t + " shipalt " + shipalt + " srf " + srf + " bdist " + bdist);
                            }
                        }
                        else
                        {
                            tend = t; //search backwards.
                            if (debugBurn)
                            {
                                Debug.Log("backward: t " + t + " shipalt " + shipalt + " srf " + srf + " bdist " + bdist);
                            }
                        }
                    } while (true);
                }
                else
                {
                    if (debugBurn)
                    {
                        Debug.Log("Can't stop, won't stop. srf:" + srfb + " " + shipalt);
                    }
                }

                if (debugBurn)
                {
                    Debug.Log("breaking dist " + brakingDist + " " + iterations);
                }

                SuicideDeltaV   = srfb.magnitude;
                SuicideAltitude = terrainAltitude + brakingDist;
                SuicideLength   = burnTime;

                r = SuicideAltitude + body.Radius;

                double costheta = a / r / e - a * e / r - 1 / e;
                if (costheta < -1d)
                {
                    costheta = -1d;
                }
                else if (costheta > 1d)
                {
                    costheta = 1d;
                }

                double burntA = -Math.Acos(costheta);

                if (debugBurn)
                {
                    Debug.Log("burnpos " + costheta + " " + vessel.orbit.pos + " " + vessel.orbit.getRelativePositionFromTrueAnomaly(burntA));
                }

                SuicideCountdown = vessel.orbit.GetDTforTrueAnomaly(burntA, double.MaxValue);

                if (SuicideCountdown < 0 && vessel.orbit.trueAnomaly > 0)
                {
                    SuicideCountdown = vessel.orbit.period + SuicideCountdown;
                }

                //this next bit is suprisingly tricky. Orbital arc distance given 2 true anomalies.
                //from http://mathforum.org/kb/servlet/JiveServlet/download/130-2391290-7852023-766514/PERIMETER%20OF%20THE%20ELLIPTICAL%20ARC%20A%20GEOMETRIC%20METHOD.pdf
                //this only works right if you're after apoapsis (same quadrant), but you should be using countdown anyway.
                double Eburn = vessel.orbit.GetEccentricAnomaly(burntA);                   //should always be a smallish negative number.
                double EShip = vessel.orbit.GetEccentricAnomaly(vessel.orbit.trueAnomaly); //why is orbit.E 0 ????
                if (EShip > 0)
                {
                    EShip = -2 * Math.PI + EShip;
                }
                double chord  = (vessel.orbit.pos - vessel.orbit.getRelativePositionFromTrueAnomaly(burntA)).magnitude;
                double dTheta = Eburn - EShip;
                double Rc     = Math.Abs(chord / 2 / Math.Sin(dTheta / 2));
                SuicideDistance = Rc * dTheta;

                if (debugBurn)
                {
                    Debug.Log("dist debug eburn " + Eburn + " eship " + EShip + " ch " + chord + " dt " + dTheta + " rc " + Rc);
                }
            }
            else
            {
                ShowDetails = false;
            }
        }
        public virtual ScienceSubject GetScienceSubject(ModuleScienceExperimentWrapper <T> baseExperiment)
        {
            var currentBiome = CurrentBiome(baseExperiment.experiment);

            return(ResearchAndDevelopment.GetExperimentSubject(baseExperiment.experiment, ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel), FlightGlobals.currentMainBody, currentBiome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, currentBiome)));
        }
Beispiel #8
0
        internal void DoScience(string expId)
        {
            string step = "Start";

            string reqResource = experiments[expId].neededResourceName;
            float  reqAmount   = 1;

            try
            {
                string msg = string.Empty;
                //Vessel ves = FlightGlobals.ActiveVessel;
                Part prt = FlightGlobals.ActiveVessel.rootPart;
                ModuleScienceExperiment exp = new ModuleScienceExperiment();
                if (experiments[expId].xmitDataScalar > 0)
                {
                    exp.xmitDataScalar = experiments[expId].xmitDataScalar;
                }
                Log.Info("DoScience, expId: " + expId + ", xmitDataScalar: " + exp.xmitDataScalar);

                // Checks
                step = "Check Boring";
                if (Utils.CheckBoring(vessel, true))
                {
                    return;
                }

                step = "Check CanRun";
                if (!Utils.CanRunExperiment(vessel, expId, ref msg))
                {
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_002", msg));
                    return;
                }

#if false
                step = "Check Insight";
                if (Utils.ResourceAvailable(prt, "Insight") < reqInsight)
                {
                    double current = Utils.ResourceAvailable(prt, "Insight");
                    double needed  = reqInsight - current;

                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_003", (int)needed));
                    return;
                }
#endif

                step = "Check Resource";
                if (Utils.ResourceAvailable(prt, reqResource) < reqAmount)
                {
                    double current = Utils.ResourceAvailable(prt, reqResource);
                    double needed  = reqAmount - current;

                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_004", (int)needed, reqResource));
                    return;
                }

                // Experiment
                step             = "Get Experiment";
                exp.experimentID = expId;
                ScienceExperiment labExp = ResearchAndDevelopment.GetExperiment(exp.experimentID);
                if (labExp == null)
                {
                    Log.Warning(Localizer.Format("#autoLOC_LTech_Experiment_005", exp.experimentID));
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_006"));
                    return;
                }

                step = "Get Situation";
                ExperimentSituations vesselSit = ScienceUtil.GetExperimentSituation(vessel);
                if (labExp.IsAvailableWhile(vesselSit, vessel.mainBody))
                {
                    step = "Get Biome";
                    string biome, displayBiome;
                    if (vessel.landedAt != string.Empty)
                    {
                        biome        = Vessel.GetLandedAtString(vessel.landedAt);
                        displayBiome = Localizer.Format(vessel.displaylandedAt);
                    }
                    else
                    {
                        biome        = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                        displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biome);
                    }

                    Log.Info("DoScience, expId: " + expId +
                             "body: " + vessel.mainBody.bodyName +
                             ", ScienceUtil.GetExperimentSituation: " + ScienceUtil.GetExperimentSituation(vessel) +
                             ", biome: " + biome);

                    SetUpActiveExperiment(expId, biome, exp, reqResource);
#if false
                    activeExperiment = new ActiveExperiment(expId, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome, exp);

                    // need to add to
                    //                   internal ExperimentSituations vesselSit;
                    //                    internal string biome;
                    ExpStatus es = new ExpStatus(expId, activeExperiment.Key, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome,
                                                 reqResource, experiments[expId].resourceAmtRequired);
                    es.active = true;
                    expStatuses.Add(es.Key, es);
                    experimentStarted = true;
                    StartCoroutine(FixedUpdate2());
#endif
                }
                else
                {
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_238424", labExp.experimentTitle));
                    Utils.DisplayScreenMsg(Localizer.Format("#autoLOC_LTech_Experiment_007", vesselSit.displayDescription()));
                }

                step = "End";
            }
            catch (Exception ex)
            {
                Log.Error($"SkylabExperiment.DoScience at step \"{step}\";. Error: {ex}");
            }
        }
Beispiel #9
0
        public void Do_SlowUpdate()
        {
            if (activeExperiment != null)
            {
                double curTime = Planetarium.GetUniversalTime();
                double delta   = curTime - lastUpdateTime;

                // Tasks
                // 1. Make sure experiment situation hasn't changed, if it has, then return
                // 2. calcualte resource usage
                // 3. Check to see if exeriment is completed, if so, set a flag

                string biome, displayBiome;
                if (vessel.landedAt != string.Empty)
                {
                    biome        = Vessel.GetLandedAtString(vessel.landedAt);
                    displayBiome = Localizer.Format(vessel.displaylandedAt);
                }
                else
                {
                    biome        = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                    displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biome);
                }

                var curExp = new ActiveExperiment(activeExperiment.activeExpid, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome);

                if ((object)curExp != null && curExp.Key == activeExperiment.Key)
                {
                    if (!expStatuses.ContainsKey(activeExperiment.Key))
                    {
                        Log.Error("Key missing from expStatuses, key: " + activeExperiment.Key);
                        foreach (var e in expStatuses.Keys)
                        {
                            Log.Error("key: " + e);
                        }
                    }
                    double resourceRequest = delta / Planetarium.fetch.fixedDeltaTime;

                    double amtNeeded = Math.Min(
                        experiments[activeExperiment.activeExpid].resourceUsageRate * resourceRequest,
                        experiments[activeExperiment.activeExpid].resourceAmtRequired - expStatuses[activeExperiment.Key].processedResource);
                    amtNeeded = amtNeeded * KCT_Interface.ResearchTimeAdjustment();

                    //Log.Info("SkylabExperiment, amtNeeded: " + amtNeeded.ToString("F3") + ",  activeExperiment.Key: " + activeExperiment.Key +
                    //    ", processedResource: " + expStatuses[activeExperiment.Key].processedResource +
                    //    ", resourceAmtRequired: " + Addon.experiments[activeExperiment.activeExpid].resourceAmtRequired);

                    double resource = part.RequestResource(experiments[activeExperiment.activeExpid].neededResourceName, amtNeeded);
                    expStatuses[activeExperiment.Key].processedResource += resource;

                    int resourceID = GetResourceID(expStatuses[activeExperiment.Key].reqResource);
                    //                    part.GetConnectedResourceTotals(resourceID, out double amount, out double maxAmount);

                    expStatuses[activeExperiment.Key].lastTimeUpdated = Planetarium.GetUniversalTime();

                    if (HighLogic.CurrentGame.Parameters.CustomParams <LTech_1>().exitWarpWhenDone)
                    {
                        var percent = 0.001 + expStatuses[activeExperiment.Key].processedResource / Addon.experiments[activeExperiment.activeExpid].resourceAmtRequired * 100;
                        if (percent >= 100f)
                        {
                            if (TimeWarp.CurrentRateIndex > 0)
                            {
                                StartCoroutine(CancelWarp());
                                //TimeWarp.fetch.CancelAutoWarp();
                                //TimeWarp.SetRate(0, true);
                            }
                        }
                    }
                    // var experiment = experiments[activeExperiment.activeExpid];
                }
                else
                {
                    Log.Info("Situation changed");
                    Utils.DisplayScreenMsg("Vessel Situation Changed, Experiment Paused");
                } // need to decide what to do if something changed
                lastUpdateTime = curTime;
            }
            else
            if (experimentStarted)
            {
                Log.Info("FixedUpdate, activeExperiment is null");
            }
        }
Beispiel #10
0
        public void Do_SlowUpdate()
        {
            if ((object)activeExperiment != null)
            {
                var curTime = Planetarium.GetUniversalTime();
                var delta   = curTime - lastUpdateTime;

                // Tasks
                // 1. Make sure experiment situation hasn't changed, if it has, then return
                // 2. calcualte resource usage
                // 3. Check to see if exeriment is completed, if so, set a flag

                string biome, displayBiome;
                if (vessel.landedAt != string.Empty)
                {
                    biome        = Vessel.GetLandedAtString(vessel.landedAt);
                    displayBiome = Localizer.Format(vessel.displaylandedAt);
                }
                else
                {
                    biome        = ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
                    displayBiome = ScienceUtil.GetBiomedisplayName(vessel.mainBody, biome);
                }
                var curExp = new ActiveExperiment(activeExperiment.activeExpid, vessel.mainBody.bodyName, ScienceUtil.GetExperimentSituation(vessel), biome);

                if ((object)curExp != null && curExp.Key == activeExperiment.Key)
                {
                    if (!expStatuses.ContainsKey(activeExperiment.Key))
                    {
                        Log.Info("Key missing from expStatuses, key: " + activeExperiment.Key);
                        foreach (var e in expStatuses.Keys)
                        {
                            Log.Info("key: " + e);
                        }
                    }
                    double resourceRequest = delta / Planetarium.fetch.fixedDeltaTime;

                    double amtNeeded = Math.Min(
                        experiments[activeExperiment.activeExpid].resourceUsageRate * resourceRequest,
                        experiments[activeExperiment.activeExpid].resourceAmtRequired - expStatuses[activeExperiment.Key].processedResource);
                    amtNeeded = amtNeeded * KCT_Interface.ResearchTimeAdjustment();

                    double resource = part.RequestResource(experiments[activeExperiment.activeExpid].neededResourceName, amtNeeded);
                    expStatuses[activeExperiment.Key].processedResource += resource;


                    int resourceID = GetResourceID(expStatuses[activeExperiment.Key].reqResource);
                    part.GetConnectedResourceTotals(resourceID, out double amount, out double maxAmount);

                    expStatuses[activeExperiment.Key].lastTimeUpdated = Planetarium.GetUniversalTime();
                    // var experiment = experiments[activeExperiment.activeExpid];
                }
                else
                {
                    Log.Info("Situation changed");
                    Utils.DisplayScreenMsg("Vessel Situation Changed, Experiment Paused");
                } // need to decide what to do if something changed
                lastUpdateTime = curTime;
            }
            else
            if (experimentStarted)
            {
                Log.Info("FixedUpdate, activeExperiment is null");
            }
        }
        public static void RegisterMethods()
        {
            RegisterMethod(new Method <Biome, string>("Name", biome => biome == null ? "" : ScienceUtil.GetBiomedisplayName(biome.body, biome.biome)));
            RegisterMethod(new Method <Biome, string>("FullName", biome => biome == null ? "" : biome.ToString()));
            RegisterMethod(new Method <Biome, CelestialBody>("CelestialBody", biome => biome == null ? null : biome.body));
            RegisterMethod(new Method <Biome, bool>("IsKSC", biome => biome == null ? false : biome.IsKSC()));
            RegisterMethod(new Method <Biome, float>("RemainingScience", RemainingScience));
            RegisterMethod(new Method <Biome, Vessel.Situations>("PrimarySituation", GetPrimarySituation));

            RegisterMethod(new Method <Biome, List <Location> >("DifficultLocations", biome => biome == null ?
                                                                new List <Location>() : BiomeTracker.GetDifficultLocations(biome.body, biome.biome).Select(v => new Location(biome.body, v.y, v.x)).ToList()));

            RegisterGlobalFunction(new Function <List <Biome> >("KSCBiomes", () => Biome.KSCBiomes.Select(b =>
                                                                                                          new Biome(FlightGlobals.Bodies.Where(cb => cb.isHomeWorld).Single(), b)).ToList(), false));
            RegisterGlobalFunction(new Function <List <Biome> >("MainKSCBiomes", () => Biome.MainKSCBiomes.Select(b =>
                                                                                                                  new Biome(FlightGlobals.Bodies.Where(cb => cb.isHomeWorld).Single(), b)).ToList(), false));
            RegisterGlobalFunction(new Function <List <Biome> >("OtherKerbinBiomes", () => Biome.OtherKerbinBiomes.Select(b =>
                                                                                                                          new Biome(FlightGlobals.Bodies.Where(cb => cb.isHomeWorld).Single(), b)).ToList(), false));
        }
        public ScienceSubject GetScienceSubject(ModuleScienceExperiment baseExperiment)
        {
            var currentExperiment = baseExperiment as DMModuleScienceAnimate;

            if (DMAPI.isAsteroidGrappled(baseExperiment))
            {
                return(DMAPI.getAsteroidSubject(currentExperiment));
            }
            else
            {
                ExperimentSituations situation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel);
                var biome = DMAPI.getBiome(baseExperiment, situation);
                if (biome == null)
                {
                    Log("Biome is null.");
                    return(null);
                }
                var scienceSubject = ResearchAndDevelopment.GetExperimentSubject(ResearchAndDevelopment.GetExperiment(currentExperiment.experimentID), situation, FlightGlobals.currentMainBody, biome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, biome));
                Log(biome, "_", situation, "_", scienceSubject == null);
                return(scienceSubject);
            }
        }
        public ScienceSubject GetScienceSubject(ModuleScienceExperiment baseExperiment)
        {
            var currentExperiment = baseExperiment as DMModuleScienceAnimateGeneric.DMModuleScienceAnimateGeneric;

            if (DMSciAnimAPI.isAsteroidGrappled(currentExperiment))
            {
                return(DMSciAnimAPI.getAsteroidSubject(currentExperiment));
            }
            else
            {
                ExperimentSituations situation = ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel);
                var biome = currentExperiment.getBiome(situation);
                return(ResearchAndDevelopment.GetExperimentSubject(ResearchAndDevelopment.GetExperiment(currentExperiment.experimentID), situation, FlightGlobals.currentMainBody, biome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, biome)));
            }
        }
Beispiel #14
0
        /// <inheritdoc />
        public override ScienceSubject GetScienceSubject(ModuleScienceExperimentWrapper <T> baseExperimentWrapper)
        {
            var scienceExperiment = ResearchAndDevelopment.GetExperiment(baseExperimentWrapper.BaseObject.experimentID);

            Log($"{nameof(GetScienceSubject)} => changed from '{baseExperimentWrapper.BaseObject.experiment?.id ?? "null"}' to '{scienceExperiment.id}')");
            var currentBiome = CurrentBiome(baseExperimentWrapper.experiment);
            var result       = ResearchAndDevelopment.GetExperimentSubject(scienceExperiment, ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel), FlightGlobals.currentMainBody, currentBiome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, currentBiome));

            Log($"{nameof(GetScienceSubject)} results in '{result.id}' / '{result.title}'");
            return(result);
        }
Beispiel #15
0
        public ScienceSubject GetScienceSubject(ModuleScienceExperiment baseExperiment)
        {
            //experiment.BiomeIsRelevantWhile
            string biome = CurrentBiome(baseExperiment.experiment);

            return(ResearchAndDevelopment.GetExperimentSubject(baseExperiment.experiment, ScienceUtil.GetExperimentSituation(FlightGlobals.ActiveVessel), FlightGlobals.currentMainBody, biome, ScienceUtil.GetBiomedisplayName(FlightGlobals.currentMainBody, biome)));
        }