private bool dataOnboard(SEP_ExperimentHandler handler, int level)
        {
            float science = handler.currentMaxScience(level);

            if (science > handler.submittedData)
            {
                if (handler.GetScienceCount() > 0)
                {
                    ScienceData dat = handler.GetData()[0];

                    ScienceSubject sub = ResearchAndDevelopment.GetSubjectByID(dat.subjectID);

                    if (sub != null)
                    {
                        float d = dat.dataAmount / sub.dataScale;

                        //SEP_Utilities.log("Science Data value check: {0:N2} - {1:N2}", logLevels.warning, science, d);

                        if (science <= d)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }

                return(false);
            }

            return(true);
        }
        public SEP_ExperimentHandler getHandler(Vessel v, uint id)
        {
            if (!experiments.Contains(v))
            {
                return(null);
            }

            List <SEP_ExperimentHandler> handlers = experiments[v];

            int l = handlers.Count;

            for (int i = 0; i < l; i++)
            {
                SEP_ExperimentHandler handler = handlers[i];

                if (handler == null)
                {
                    continue;
                }

                if (!handler.loaded)
                {
                    continue;
                }

                if (handler.flightID == id)
                {
                    return(handler);
                }
            }

            return(null);
        }
        public static ScienceSubject subjectIsValid(SEP_ExperimentHandler handler)
        {
            ScienceSubject subject = null;

            List <ScienceSubject> subjects = ResearchAndDevelopment.GetSubjects();

            if (subjects == null || subjects.Count <= 0)
            {
                return(null);
            }

            for (int i = 1; i <= 3; i++)
            {
                ScienceExperiment exp = handler.getExperimentLevel(i);

                if (exp == null)
                {
                    continue;
                }

                string biome = currentBiome(exp, handler.vessel);

                string id = string.Format("{0}@{1}{2}{3}", exp.id, handler.vessel.mainBody.name, ExperimentSituations.SrfLanded, biome);

                if (subjects.Any(s => s.id == id))
                {
                    subject = ResearchAndDevelopment.GetSubjectByID(id);
                    //log("Subject ID Confirmed: Science Level - {0:N2}", logLevels.warning, subject.science);
                }

                //log("Subject ID Checked: ID {0}", logLevels.warning, id);
            }

            return(subject);
        }
        private bool checkTransmission(SEP_ExperimentHandler exp)
        {
            int   level   = exp.getMaxLevel(false);
            float science = exp.currentMaxScience(level);

            if (science > exp.submittedData)
            {
                return(transmitData(exp, level, exp.submittedData, science));
            }

            return(false);
        }
        private bool checkTransmission(SEP_ExperimentHandler exp)
        {
            int   level   = exp.getMaxLevel(false);
            float science = exp.currentMaxScience(level);

            //SEP_Utilities.log("Science Value Check: {0}\nVessel: {1}\nScience: {2:F4}\nSubmitted Science: {3:F4}", logLevels.warning, exp.experimentTitle, exp.vessel.vesselName, science, exp.submittedData);

            if (science > (exp.submittedData + (science / 10)))
            {
                return(transmitData(exp, level, exp.submittedData, science));
            }

            return(false);
        }
        private void OnDestroy()
        {
            running = false;

            GameEvents.onLevelWasLoaded.Remove(onReady);

            var handlers = experiments.SelectMany(e => e.Value).ToList();

            int l = handlers.Count;

            for (int i = 0; i < l; i++)
            {
                SEP_ExperimentHandler handler = handlers[i];

                handler.OnDestroy();
            }
        }
Exemple #7
0
        private IEnumerator delayedLoad(ConfigNode node)
        {
            //SEPUtilities.log("Delayed SEP Science Experiment Loading...", logLevels.warning);

            int timer = 0;

            while (!FlightGlobals.ready)
            {
                yield return(null);
            }

            while (timer < 10)
            {
                timer++;
                yield return(null);
            }

            flightID = part.flightID;

            if (SEP_Controller.Instance.VesselLoaded(vessel))
            {
                handler = SEP_Controller.Instance.getHandler(vessel, part.flightID);

                if (handler == null)
                {
                    handler = new SEP_ExperimentHandler(this, node);
                }
                else
                {
                    handler.host = this;
                }
            }
            else
            {
                handler = new SEP_ExperimentHandler(this, node);
            }

            if (handler == null)
            {
                yield break;
            }

            //SEPUtilities.log("SEP Science Experiment Loading...", logLevels.warning);

            delayedEvents();
        }
        public static ScienceData getScienceData(SEP_ExperimentHandler handler, ScienceExperiment exp, int level)
        {
            ScienceData data = null;

            string biome        = currentBiome(exp, handler.vessel);
            string displayBiome = currentDisplayBiome(exp, handler.vessel);

            ScienceSubject sub = ResearchAndDevelopment.GetExperimentSubject(exp, ExperimentSituations.SrfLanded, handler.vessel.mainBody, biome, displayBiome);

            sub.science         = handler.submittedData * sub.subjectValue;
            sub.scientificValue = 1 - (sub.science / sub.scienceCap);

            data = new ScienceData(exp.baseValue * exp.dataScale, handler.xmitDataScalar, 1, sub.id, sub.title, false, (uint)handler.flightID);

            //log("Science Data Generated: {0} - Data: {1:F2} - Xmit: {2:F2}", logLevels.warning, data.subjectID, data.dataAmount, data.baseTransmitValue);

            return(data);
        }
        public static ScienceData getScienceData(SEP_ExperimentHandler handler, ScienceExperiment exp, int level)
        {
            ScienceData data = null;

            string biome = currentBiome(exp, handler.vessel);

            ScienceSubject sub = ResearchAndDevelopment.GetExperimentSubject(exp, ExperimentSituations.SrfLanded, handler.vessel.mainBody, biome);

            sub.title = exp.experimentTitle + situationCleanup(handler.vessel.mainBody, ExperimentSituations.SrfLanded, biome);

            sub.science         = handler.submittedData * sub.subjectValue;
            sub.scientificValue = 1 - (sub.science / sub.scienceCap);

            data = new ScienceData(exp.baseValue * exp.dataScale, handler.xmitDataScalar, handler.vessel.VesselValues.ScienceReturn.value, sub.id, sub.title, false, (uint)handler.flightID);

            //log("Science Data Generated: {0}", logLevels.warning, data.subjectID);

            return(data);
        }
        private void OnDestroy()
        {
            if (instance == this)
            {
                instance = null;
            }

            GameEvents.onLevelWasLoaded.Remove(onReady);
            GameEvents.OnGameSettingsApplied.Remove(onSettingsApplied);

            var handlers = experiments.Values.SelectMany(e => e).ToList();

            int l = handlers.Count;

            for (int i = 0; i < l; i++)
            {
                SEP_ExperimentHandler handler = handlers[i];

                handler.OnDestroy();
            }
        }
        public static ScienceSubject checkAndUpdateRelatedSubjects(SEP_ExperimentHandler handler, int level, float data, float submitted)
        {
            ScienceSubject subject = null;

            for (int i = 1; i <= level; i++)
            {
                ScienceExperiment exp = handler.getExperimentLevel(i);

                if (exp == null)
                {
                    continue;
                }

                string biome = currentBiome(exp, handler.vessel);

                subject       = ResearchAndDevelopment.GetExperimentSubject(exp, ExperimentSituations.SrfLanded, handler.vessel.mainBody, biome);
                subject.title = exp.experimentTitle + situationCleanup(handler.vessel.mainBody, ExperimentSituations.SrfLanded, biome);

                if (i == level)
                {
                    subject.science = submitted * subject.subjectValue;
                }
                else
                {
                    subject.science = data * subject.subjectValue;
                }

                if (subject.science > subject.scienceCap)
                {
                    subject.science = subject.scienceCap;
                }

                subject.scientificValue = 1 - (subject.science / subject.scienceCap);

                //log("Related Subject Checked: ID {0} - Science Level {1:N0}", logLevels.warning, subject.id, subject.science);
            }

            return(subject);
        }
        private bool transmitData(SEP_ExperimentHandler exp, int level, float submittedData, float newData)
        {
            ScienceData data = SEP_Utilities.getScienceData(exp, exp.getExperimentLevel(level), level);

            if (exp.vessel.loaded)
            {
                IScienceDataTransmitter bestTransmitter = ScienceUtil.GetBestTransmitter(exp.vessel);

                if (bestTransmitter != null)
                {
                    ScienceExperiment e = exp.getExperimentLevel(level);

                    float transmitterCost = getLoadedTransmitterCost(bestTransmitter);

                    float ecCost = newData * e.dataScale * transmitterCost;

                    if (ecCost > SEP_Utilities.getTotalVesselEC(exp.vessel))
                    {
                        if (!dataOnboard(exp, level))
                        {
                            SEP_Utilities.log("Not enough power for transmissionon this vessel: {1}; saving data: {0}", logLevels.log, data.title, exp.vessel.vesselName);
                            exp.addData(data);
                            if (exp.host != null)
                            {
                                exp.host.Events["ReviewDataEvent"].active   = true;
                                exp.host.Events["TransferDataEvent"].active = exp.host.hasContainer;
                                exp.host.Events["CollectData"].active       = true;
                                if (exp.host.Controller != null)
                                {
                                    exp.host.Controller.setCollectEvent();
                                }
                            }
                        }
                        return(false);
                    }

                    SEP_Utilities.log("Sending data to vessel comms: {0}", logLevels.log, data.title);
                    bestTransmitter.TransmitData(new List <ScienceData> {
                        data
                    });
                    return(true);
                }
                else
                {
                    if (!dataOnboard(exp, level))
                    {
                        SEP_Utilities.log("No Comms Devices on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.vesselName);
                        exp.addData(data);
                        if (exp.host != null)
                        {
                            exp.host.Events["ReviewDataEvent"].active   = true;
                            exp.host.Events["TransferDataEvent"].active = exp.host.hasContainer;
                            exp.host.Events["CollectData"].active       = true;
                            if (exp.host.Controller != null)
                            {
                                exp.host.Controller.setCollectEvent();
                            }
                        }
                    }
                    return(false);
                }
            }
            else
            {
                List <ProtoPartSnapshot> transmitters = getProtoTransmitters(exp.vessel.protoVessel);

                float?transmitterCost = getBestTransmitterCost(transmitters);

                if (transmitterCost == null)
                {
                    if (!dataOnboard(exp, level))
                    {
                        SEP_Utilities.log("No Comms Devices on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.protoVessel.vesselName);
                        exp.addData(data);
                    }
                    return(false);
                }

                //SEP_Utilities.log("Transmission Score: {0:N4}EC", logLevels.warning, transmitterCost);

                ScienceExperiment e = exp.getExperimentLevel(level);

                float ecCost = newData * e.dataScale * (float)transmitterCost;

                //SEP_Utilities.log("Transmission Cost: {0:N4}EC", logLevels.warning, ecCost);

                if (ecCost > SEP_Utilities.getTotalVesselEC(exp.vessel.protoVessel))
                {
                    if (!dataOnboard(exp, level))
                    {
                        SEP_Utilities.log("Not enough electricity on this vessel: {1}. Cannot Transmit Data; saving data: {0}", logLevels.log, data.title, exp.vessel.protoVessel.vesselName);
                        exp.addData(data);
                    }
                    return(false);
                }

                ScienceSubject sub = SEP_Utilities.checkAndUpdateRelatedSubjects(exp, level, newData, submittedData);

                if (sub == null)
                {
                    return(false);
                }

                ResearchAndDevelopment.Instance.SubmitScienceData(newData * sub.dataScale, sub, 1, exp.vessel.protoVessel);

                if (exp.vessel.HasValidContractObjectives(new List <string> {
                    "Generator"
                }))
                {
                    consumeResources(exp.vessel.protoVessel, ecCost);
                }

                exp.submittedData += (newData - submittedData);

                return(true);
            }
        }
        private void experimentCheck(double time)
        {
            int l = experiments.Count;

            //if (l > 0)
            //SEP_Utilities.log("Performing SEP background check on {0} experiments at time: {1:N0}", logLevels.log, l , time);

            for (int i = 0; i < l; i++)
            {
                List <SEP_ExperimentHandler> modules = experiments.At(i);

                int c = modules.Count;

                for (int j = 0; j < c; j++)
                {
                    SEP_ExperimentHandler m = modules[j];

                    if (m == null)
                    {
                        continue;
                    }

                    if (!m.loaded)
                    {
                        continue;
                    }

                    if (!m.vessel.Landed)
                    {
                        continue;
                    }

                    if (!m.experimentRunning)
                    {
                        continue;
                    }

                    if (m.usingECResource && !m.vessel.loaded)
                    {
                        if (!m.vessel.HasValidContractObjectives(new List <string> {
                            "Generator"
                        }))
                        {
                            continue;
                        }
                    }

                    if (m.vessel.loaded)
                    {
                        if (m.host != null && m.host.Controller != null)
                        {
                            if (m.host.vessel != m.host.Controller.vessel)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }

                    double t = m.experimentTime;

                    float calib = m.calibration;

                    if (usingCommNet)
                    {
                        if (m.vessel.Connection != null)
                        {
                            float signal = (float)m.vessel.Connection.SignalStrength - 0.5f;

                            if (signal < 0)
                            {
                                signal /= 2;
                            }

                            float bonus = calib * signal;

                            calib += bonus;
                        }
                    }

                    t /= calib;

                    double length = time - m.lastBackgroundCheck;

                    m.lastBackgroundCheck = time;

                    double days = length / 21600;

                    if (days < t)
                    {
                        double n = days / t;

                        //SEPUtilities.log("Updating SEP Experiment Handler [{0}]: Add {1:P6}", logLevels.warning, m.experimentTitle, n);

                        m.completion += (float)n;
                    }
                    else
                    {
                        m.completion = 1;
                    }

                    float max = m.getMaxCompletion();

                    if (max <= 0.5f)
                    {
                        if (m.completion >= 0.5f)
                        {
                            m.completion = 0.5f;
                        }
                    }
                    else if (max <= 0.75f)
                    {
                        if (m.completion >= 0.75f)
                        {
                            m.completion = 0.75f;
                        }
                    }
                    else
                    {
                        if (m.completion >= 1f)
                        {
                            m.completion = 1f;
                        }
                    }

                    bool transmitted = false;

                    m.submittedData = m.getSubmittedData();

                    if (m.canTransmit && m.controllerAutoTransmit && transmissionUpgrade)
                    {
                        transmitted = checkTransmission(m);
                    }
                    else
                    {
                        int level = m.getMaxLevel(false);

                        if (!dataOnboard(m, level))
                        {
                            m.addData(SEP_Utilities.getScienceData(m, m.getExperimentLevel(level), level));

                            if (m.vessel.loaded && m.host != null)
                            {
                                m.host.Events["ReviewDataEvent"].active   = true;
                                m.host.Events["TransferDataEvent"].active = m.host.hasContainer;
                                m.host.Events["CollectData"].active       = true;
                                if (m.host.Controller != null)
                                {
                                    m.host.Controller.setCollectEvent();
                                }
                            }
                        }
                    }

                    if (transmitted)
                    {
                        m.clearData();
                    }

                    if (m.completion >= max)
                    {
                        m.experimentRunning = false;
                        if (m.vessel.loaded && m.host != null)
                        {
                            int count = m.GetScienceCount();
                            m.host.Events["ReviewDataEvent"].active   = !transmitted && count > 0;
                            m.host.Events["TransferDataEvent"].active = !transmitted && count > 0 && m.host.hasContainer;
                            m.host.Events["CollectData"].active       = !transmitted && count > 0;
                            m.host.PauseExperiment();
                            if (m.host.Controller != null)
                            {
                                m.host.Controller.setCollectEvent();
                            }
                        }
                    }
                }
            }
        }
        private void populateExperiments()
        {
            experiments = new DictionaryValueList <Vessel, List <SEP_ExperimentHandler> >();

            int l = FlightGlobals.Vessels.Count;

            for (int i = 0; i < l; i++)
            {
                Vessel v = FlightGlobals.Vessels[i];

                if (v == null)
                {
                    continue;
                }

                if (v.vesselType == VesselType.Debris)
                {
                    continue;
                }

                if (experiments.Contains(v))
                {
                    continue;
                }

                List <SEP_ExperimentHandler> handlers = new List <SEP_ExperimentHandler>();

                if (v.loaded)
                {
                    handlers =
                        (from mod in v.FindPartModulesImplementing <ModuleSEPScienceExperiment>()
                         where mod.Handler != null && mod.IsDeployed
                         select mod.Handler).ToList();
                }
                else
                {
                    var snaps = v.protoVessel.protoPartSnapshots;

                    int s = snaps.Count;

                    for (int j = 0; j < s; j++)
                    {
                        ProtoPartSnapshot p = snaps[j];

                        if (!p.modules.Any(m => m.moduleName == "ModuleSEPScienceExperiment"))
                        {
                            continue;
                        }

                        var mods = p.modules;

                        int d = mods.Count;

                        for (int k = 0; k < d; k++)
                        {
                            ProtoPartModuleSnapshot mod = mods[k];

                            if (mod.moduleName != "ModuleSEPScienceExperiment")
                            {
                                continue;
                            }

                            if (!mod.moduleValues.HasValue("IsDeployed") || mod.moduleValues.GetValue("IsDeployed") != "True")
                            {
                                continue;
                            }

                            SEP_ExperimentHandler handler = new SEP_ExperimentHandler(mod, v);

                            if (handler.loaded)
                            {
                                handlers.Add(handler);
                            }
                        }
                    }
                }

                if (handlers.Count > 0)
                {
                    if (VesselUtilities.VesselHasModuleName("ModuleSEPStation", v))
                    {
                        experiments.Add(v, handlers);
                    }
                }
            }

            setup = true;
        }
        private bool transmitData(SEP_ExperimentHandler exp, int level, float submittedData, float newData)
        {
            if (exp.vessel.loaded)
            {
                List <IScienceDataTransmitter> tranList = exp.vessel.FindPartModulesImplementing <IScienceDataTransmitter>();
                ScienceData data = SEP_Utilities.getScienceData(exp, exp.getExperimentLevel(level), level);
                if (tranList.Count > 0)
                {
                    SEP_Utilities.log("Sending data to vessel comms. {0} devices to choose from. Will try to pick the best one", logLevels.log, tranList.Count);
                    tranList.OrderBy(ScienceUtil.GetTransmitterScore).First().TransmitData(new List <ScienceData> {
                        data
                    });
                    return(true);
                }
                else
                {
                    exp.addData(data);
                    if (exp.vessel.loaded && exp.host != null)
                    {
                        exp.host.Events["ReviewDataEvent"].active = true;
                        exp.host.Events["CollectData"].active     = true;
                        if (exp.host.Controller != null)
                        {
                            exp.host.Controller.setCollectEvent();
                        }
                    }
                    return(false);
                }
            }
            else
            {
                List <ProtoPartSnapshot> transmitters = getProtoTransmitters(exp.vessel.protoVessel);

                float?transmitterCost = getBestTransmitterCost(transmitters);

                if (transmitterCost == null)
                {
                    exp.addData(SEP_Utilities.getScienceData(exp, exp.getExperimentLevel(level), level));
                    return(false);
                }

                //SEPUtilities.log("Transmission Score: {0:N4}EC", logLevels.warning, transmitterCost);

                ScienceExperiment e = exp.getExperimentLevel(level);

                float ecCost = newData * e.dataScale * (float)transmitterCost;

                //SEPUtilities.log("Transmission Cost: {0:N4}EC", logLevels.warning, ecCost);

                if (ecCost > SEP_Utilities.getTotalVesselEC(exp.vessel.protoVessel))
                {
                    exp.addData(SEP_Utilities.getScienceData(exp, exp.getExperimentLevel(level), level));
                    return(false);
                }

                ScienceSubject sub = SEP_Utilities.checkAndUpdateRelatedSubjects(exp, level, newData, submittedData);

                if (sub == null)
                {
                    return(false);
                }

                ResearchAndDevelopment.Instance.SubmitScienceData(newData * sub.dataScale, sub, 1, exp.vessel.protoVessel);

                List <string> generators = FinePrint.ContractDefs.GetModules("Power");

                if (!FinePrint.Utilities.VesselUtilities.VesselHasAnyModules(generators, exp.vessel))
                {
                    consumeResources(exp.vessel.protoVessel, ecCost);
                }

                exp.submittedData += (newData - submittedData);

                return(true);
            }
        }
        private void experimentCheck(double time)
        {
            int l = experiments.Count;

            if (l > 0)
            {
                SEP_Utilities.log("Performing SEP background check on {0} experiments at time: {1:N0}", logLevels.log, l, time);
            }

            for (int i = 0; i < l; i++)
            {
                List <SEP_ExperimentHandler> modules = experiments.ElementAt(i).Value;

                int c = modules.Count;

                for (int j = 0; j < c; j++)
                {
                    SEP_ExperimentHandler m = modules[j];

                    if (m == null)
                    {
                        continue;
                    }

                    if (!m.loaded)
                    {
                        continue;
                    }

                    if (!m.experimentRunning)
                    {
                        continue;
                    }

                    if (m.usingECResource && !m.vessel.loaded)
                    {
                        List <string> generators = FinePrint.ContractDefs.GetModules("Power");

                        if (!FinePrint.Utilities.VesselUtilities.VesselHasAnyModules(generators, m.vessel))
                        {
                            continue;
                        }
                    }

                    if (m.vessel.loaded)
                    {
                        if (m.host != null && m.host.Controller != null)
                        {
                            if (m.host.vessel != m.host.Controller.vessel)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }

                    double t = m.experimentTime;

                    t /= m.calibration;

                    double length = time - m.lastBackgroundCheck;

                    m.lastBackgroundCheck = time;

                    double days = length / 21600;

                    if (days < t)
                    {
                        double n = days / t;

                        //SEPUtilities.log("Updating SEP Experiment Handler [{0}]: Add {1:P6}", logLevels.warning, m.experimentTitle, n);

                        m.completion += (float)n;
                    }
                    else
                    {
                        m.completion = 1;
                    }

                    float max = m.getMaxCompletion();

                    if (max <= 0.5f)
                    {
                        if (m.completion >= 0.5f)
                        {
                            m.completion = 0.5f;
                        }
                    }
                    else if (max <= 0.75f)
                    {
                        if (m.completion >= 0.75f)
                        {
                            m.completion = 0.75f;
                        }
                    }
                    else
                    {
                        if (m.completion >= 1f)
                        {
                            m.completion = 1f;
                        }
                    }

                    bool transmitted = false;

                    m.submittedData = m.getSubmittedData();

                    if (m.canTransmit && m.controllerAutoTransmit && transmissionUpgrade)
                    {
                        transmitted = checkTransmission(m);
                    }
                    else
                    {
                        int   level   = m.getMaxLevel(false);
                        float science = m.currentMaxScience(level);

                        if (science > m.submittedData)
                        {
                            bool flag = true;
                            if (m.GetScienceCount() > 0)
                            {
                                ScienceData dat = m.GetData()[0];

                                ScienceSubject sub = ResearchAndDevelopment.GetSubjectByID(dat.subjectID);

                                if (sub != null)
                                {
                                    float d = dat.dataAmount / sub.dataScale;

                                    //SEPUtilities.log("Science Data value check: {0:N2} - {1:N2}", logLevels.warning, science, d);

                                    if (science <= d)
                                    {
                                        flag = false;
                                    }
                                }
                                else
                                {
                                    flag = false;
                                }
                            }

                            if (flag)
                            {
                                m.addData(SEP_Utilities.getScienceData(m, m.getExperimentLevel(level), level));

                                if (m.vessel.loaded && m.host != null)
                                {
                                    m.host.Events["ReviewDataEvent"].active = true;
                                    m.host.Events["CollectData"].active     = true;
                                    if (m.host.Controller != null)
                                    {
                                        m.host.Controller.setCollectEvent();
                                    }
                                }
                            }
                        }
                    }

                    if (transmitted)
                    {
                        m.clearData();
                    }

                    if (m.completion >= max)
                    {
                        m.experimentRunning = false;
                        if (m.vessel.loaded && m.host != null)
                        {
                            int count = m.GetScienceCount();
                            m.host.Events["ReviewDataEvent"].active = !transmitted && count > 0;
                            m.host.Events["CollectData"].active     = !transmitted && count > 0;
                            m.host.PauseExperiment();
                            if (m.host.Controller != null)
                            {
                                m.host.Controller.setCollectEvent();
                            }
                        }
                    }
                }
            }
        }