Esempio n. 1
0
        // consume EC for transmission, and transmit science data
        public static void Update(Vessel v, VesselData vd, ResourceInfo ec, double elapsed_s)
        {
            // do nothing if science system is disabled
            if (!Features.Science)
            {
                return;
            }

            // consume ec for transmitters
            ec.Consume(vd.Connection.ec_idle * elapsed_s, ResourceBroker.CommsIdle);

            // avoid corner-case when RnD isn't live during scene changes
            // - this avoid losing science if the buffer reach threshold during a scene change
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX && ResearchAndDevelopment.Instance == null)
            {
                return;
            }

            // clear list of files transmitted
            vd.filesTransmitted.Clear();

            // check connection
            if (vd.Connection == null ||
                !vd.Connection.linked ||
                vd.Connection.rate <= 0.0 ||
                !vd.deviceTransmit ||
                ec.Amount < vd.Connection.ec_idle * elapsed_s)
            {
                // reset all files transmit rate
                foreach (Drive drive in Drive.GetDrives(vd, true))
                {
                    foreach (File f in drive.files.Values)
                    {
                        f.transmitRate = 0.0;
                    }
                }

                // do nothing else
                return;
            }

            double totalTransmitCapacity     = vd.Connection.rate * elapsed_s;
            double remainingTransmitCapacity = totalTransmitCapacity;

            GetFilesToTransmit(v, vd);

            if (xmitFiles.Count == 0)
            {
                return;
            }

            UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Science.Update-Loop");

            // traverse the list in reverse because :
            // - warp cache files are at the end, and they are always transmitted regerdless of transmit capacity
            // - others files are next, sorted in science value per MB ascending order
            for (int i = xmitFiles.Count - 1; i >= 0; i--)
            {
                XmitFile xmitFile = xmitFiles[i];

                if (xmitFile.file.size == 0.0)
                {
                    continue;
                }

                // always transmit everything in the warp cache
                if (!xmitFile.isInWarpCache && remainingTransmitCapacity <= 0.0)
                {
                    break;
                }

                // determine how much data is transmitted
                double transmitted = xmitFile.isInWarpCache ? xmitFile.file.size : Math.Min(xmitFile.file.size, remainingTransmitCapacity);

                if (transmitted == 0.0)
                {
                    continue;
                }

                // consume transmit capacity
                remainingTransmitCapacity -= transmitted;

                // get science value
                double xmitScienceValue = transmitted * xmitFile.sciencePerMB;

                // consume data in the file
                xmitFile.file.size -= transmitted;

                // remove science collected (ignoring final science value clamped to subject completion)
                xmitFile.file.subjectData.RemoveScienceCollectedInFlight(xmitScienceValue);

                // save transmit rate for the file, and add it to the VesselData list of files being transmitted
                if (xmitFile.isInWarpCache && xmitFile.realDriveFile != null)
                {
                    xmitFile.realDriveFile.transmitRate = transmitted / elapsed_s;
                    vd.filesTransmitted.Add(xmitFile.realDriveFile);
                }
                else
                {
                    xmitFile.file.transmitRate = transmitted / elapsed_s;
                    vd.filesTransmitted.Add(xmitFile.file);
                }

                if (xmitScienceValue > 0.0)
                {
                    // add science to the subject (and eventually included subjects), trigger completion events, credit the science, return how much has been credited.
                    vd.scienceTransmitted += xmitFile.file.subjectData.RetrieveScience(xmitScienceValue, true, v.protoVessel, xmitFile.file);
                }
            }

            UnityEngine.Profiling.Profiler.EndSample();

            // consume EC cost for transmission (ec_idle is consumed above)
            double transmittedCapacity = totalTransmitCapacity - remainingTransmitCapacity;
            double transmissionCost    = (vd.Connection.ec - vd.Connection.ec_idle) * (transmittedCapacity / (vd.Connection.rate * elapsed_s));

            ec.Consume(transmissionCost * elapsed_s, ResourceBroker.CommsXmit);
        }
Esempio n. 2
0
        // consume EC for transmission, and transmit science data
        public static void Update(Vessel v, VesselData vd, ResourceInfo ec, double elapsed_s)
        {
            // do nothing if science system is disabled
            if (!Features.Science)
            {
                return;
            }

            // consume ec for transmitters
            ec.Consume(vd.Connection.ec_idle * elapsed_s, ResourceBroker.CommsIdle);

            // avoid corner-case when RnD isn't live during scene changes
            // - this avoid losing science if the buffer reach threshold during a scene change
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX && ResearchAndDevelopment.Instance == null)
            {
                return;
            }

            // clear list of files transmitted
            vd.filesTransmitted.Clear();

            // check connection
            if (vd.Connection == null ||
                !vd.Connection.linked ||
                vd.Connection.rate <= 0.0 ||
                !vd.deviceTransmit ||
                ec.Amount < vd.Connection.ec_idle * elapsed_s)
            {
                // reset all files transmit rate
                foreach (Drive drive in Drive.GetDrives(vd, true))
                {
                    foreach (File f in drive.files.Values)
                    {
                        f.transmitRate = 0.0;
                    }
                }

                // do nothing else
                return;
            }

            double totalTransmitCapacity     = vd.Connection.rate * elapsed_s;
            double remainingTransmitCapacity = totalTransmitCapacity;
            double scienceCredited           = 0.0;

            GetFilesToTransmit(v, vd);

            if (xmitFiles.Count == 0)
            {
                return;
            }

            UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Science.Update-Loop");

            // traverse the list in reverse because :
            // - warp cache files are at the end, and they are always transmitted regerdless of transmit capacity
            // - others files are next, sorted in science value per MB ascending order
            for (int i = xmitFiles.Count - 1; i >= 0; i--)
            {
                XmitFile xmitFile = xmitFiles[i];

                if (xmitFile.file.size == 0.0)
                {
                    continue;
                }

                // always transmit everything in the warp cache
                if (!xmitFile.isInWarpCache && remainingTransmitCapacity <= 0.0)
                {
                    break;
                }

                // determine how much data is transmitted
                double transmitted = xmitFile.isInWarpCache ? xmitFile.file.size : Math.Min(xmitFile.file.size, remainingTransmitCapacity);

                if (transmitted == 0.0)
                {
                    continue;
                }

                // consume transmit capacity
                remainingTransmitCapacity -= transmitted;

                // get science value
                double xmitScienceValue = transmitted * xmitFile.sciencePerMB;

                // consume data in the file
                xmitFile.file.size -= transmitted;

                // remove science collected (ignoring final science value clamped to subject completion)
                xmitFile.file.subjectData.RemoveScienceCollectedInFlight(xmitScienceValue);

                // fire subject completed events
                int timesCompleted = xmitFile.file.subjectData.UpdateSubjectCompletion(xmitScienceValue);
                if (timesCompleted > 0)
                {
                    SubjectXmitCompleted(xmitFile.file, timesCompleted, v);
                }

                // save transmit rate for the file, and add it to the VesselData list of files being transmitted
                if (xmitFile.isInWarpCache && xmitFile.realDriveFile != null)
                {
                    xmitFile.realDriveFile.transmitRate = transmitted / elapsed_s;
                    vd.filesTransmitted.Add(xmitFile.realDriveFile);
                }
                else
                {
                    xmitFile.file.transmitRate = transmitted / elapsed_s;
                    vd.filesTransmitted.Add(xmitFile.file);
                }

                // clamp science value to subject max value
                xmitScienceValue = Math.Min(xmitScienceValue, xmitFile.file.subjectData.ScienceRemainingToRetrieve);

                if (xmitScienceValue > 0.0)
                {
                    // add credits
                    scienceCredited += xmitScienceValue;

                    // credit the subject
                    xmitFile.file.subjectData.AddScienceToRnDSubject(xmitScienceValue);
                }
            }

            UnityEngine.Profiling.Profiler.EndSample();

            vd.scienceTransmitted += scienceCredited;

            // consume EC cost for transmission (ec_idle is consumed above)
            double transmittedCapacity = totalTransmitCapacity - remainingTransmitCapacity;
            double transmissionCost    = (vd.Connection.ec - vd.Connection.ec_idle) * (transmittedCapacity / vd.Connection.rate);

            ec.Consume(transmissionCost, ResourceBroker.CommsXmit);

            UnityEngine.Profiling.Profiler.BeginSample("Kerbalism.Science.Update-AddScience");

            // Add science points, but wait until we have at least 0.1 points to add because AddScience is VERY slow
            // We don't use "TransactionReasons.ScienceTransmission" because AddScience fire multiple events not meant to be fired continuously
            // this avoid many side issues (ex : chatterer transmit sound playing continously, strategia "+0.0 science" popup...)
            ScienceDB.uncreditedScience += scienceCredited;
            if (ScienceDB.uncreditedScience > 0.1)
            {
                if (GameHasRnD)
                {
                    ResearchAndDevelopment.Instance.AddScience((float)ScienceDB.uncreditedScience, TransactionReasons.None);
                }

                ScienceDB.uncreditedScience = 0.0;
            }

            UnityEngine.Profiling.Profiler.EndSample();
        }