public static void ProcessUnloadedPersistentEngines(VesselData vesselData, double elapsedTime)
        {
            // ignore landed or floating vessels
            if (vesselData.Vessel.LandedOrSplashed)
            {
                return;
            }

            vesselData.PersistentThrust = 0;

            foreach (KeyValuePair <uint, PersistentEngineData> keyValuePair in vesselData.Engines)
            {
                PersistentEngineData persistentEngineData = keyValuePair.Value;

                // update snapshots
                persistentEngineData.ProtoPartSnapshot       = vesselData.Vessel.protoVessel.protoPartSnapshots[persistentEngineData.PartIndex];
                persistentEngineData.ProtoPartModuleSnapshot = persistentEngineData.ProtoPartSnapshot.modules[persistentEngineData.ModuleIndex];

                // update persistentThrust
                double.TryParse(persistentEngineData.ProtoPartModuleSnapshot.moduleValues.GetValue(nameof(persistentEngineData.PersistentEngine.persistentThrust)), out persistentEngineData.PersistentEngine.persistentThrust);
                if (persistentEngineData.PersistentEngine.persistentThrust <= 0)
                {
                    continue;
                }

                float.TryParse(persistentEngineData.ProtoPartModuleSnapshot.moduleValues.GetValue(nameof(persistentEngineData.PersistentEngine.maxThrust)), out persistentEngineData.PersistentEngine.maxThrust);
                if (persistentEngineData.PersistentEngine.maxThrust <= 0)
                {
                    persistentEngineData.PersistentEngine.maxThrust = (float)persistentEngineData.PersistentEngine.persistentThrust;
                }

                vesselData.PersistentThrust += persistentEngineData.PersistentEngine.persistentThrust;

                var resourceChangeRequests = new List <KeyValuePair <string, double> >();

                ProcessUnloadedPersistentEngine(persistentEngineData.ProtoPartSnapshot, vesselData, resourceChangeRequests, elapsedTime);

                foreach (KeyValuePair <string, double> resourceChangeRequest in resourceChangeRequests)
                {
                    vesselData.ResourceChange(resourceChangeRequest.Key, resourceChangeRequest.Value);
                }
            }
        }
Пример #2
0
        public void UpdateUnloadedVesselData()
        {
            // clear reference dictionaries
            foreach (var vesselDataResourceChange in ResourceChanges)
            {
                vesselDataResourceChange.Value.Change = 0;
            }

            // clear value dictionaries
            AvailableResources.Clear();
            MaxAmountResources.Clear();
            AvailableStorage.Clear();

            Position            = Vessel.GetWorldPos3D();
            Orbit               = Vessel.GetOrbit();
            OrbitalVelocityAtUt = Orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;

            // calculate heading vector once per frame per vessel
            HeadingVector = EngineBackgroundProcessing.GetHeadingVectorForAutoPilot(vesselData: this, UT: Planetarium.GetUniversalTime());

            if (HeadingVector != Vector3d.zero && DeltaTime != 0)
            {
                // apply Perturb once per frame per vessel
                AccelerationVector = Vector3d.zero;
                foreach (KeyValuePair <uint, PersistentEngineData> engineData in Engines)
                {
                    PersistentEngineData persistentEngineData = engineData.Value;

                    persistentEngineData.DeltaVVector = persistentEngineData.DeltaV * HeadingVector.normalized * persistentEngineData.PersistentEngine.cosine;
                    AccelerationVector += persistentEngineData.DeltaVVector / DeltaTime;
                }

                Orbit.Perturb(AccelerationVector * TimeWarp.fixedDeltaTime, Planetarium.GetUniversalTime());
            }

            // calculate vessel mass and total resource amounts
            TotalVesselMassInTon = 0;
            foreach (ProtoPartSnapshot protoPartSnapshot in Vessel.protoVessel.protoPartSnapshots)
            {
                TotalVesselMassInTon += protoPartSnapshot.mass;
                foreach (ProtoPartResourceSnapshot protoPartResourceSnapshot in protoPartSnapshot.resources)
                {
                    if (protoPartResourceSnapshot.definition == null)
                    {
                        continue;
                    }

                    TotalVesselMassInTon += protoPartResourceSnapshot.amount * protoPartResourceSnapshot.definition.density;

                    MaxAmountResources.TryGetValue(protoPartResourceSnapshot.resourceName, out double maxAmount);
                    MaxAmountResources[protoPartResourceSnapshot.resourceName] = maxAmount + protoPartResourceSnapshot.maxAmount;

                    UpdateAvailableResource(protoPartResourceSnapshot.resourceName, Math.Min(protoPartResourceSnapshot.maxAmount, protoPartResourceSnapshot.amount));
                }
            }
            TotalVesselMassInKg = TotalVesselMassInTon * 1000;

            // calculate storage room for resources
            foreach (KeyValuePair <string, double> availableResource in AvailableResources)
            {
                AvailableResources.TryGetValue(availableResource.Key, out double availableAmount);
                MaxAmountResources.TryGetValue(availableResource.Key, out double maxAmount);
                AvailableStorage[availableResource.Key] = maxAmount - availableAmount;
            }
        }
        public static PersistentEngineData LoadPersistentEngine(int partIndex, ProtoPartSnapshot protoPartSnapshot,
                                                                VesselData vesselData, Part protoPart)
        {
            var persistentEngine = protoPart?.FindModuleImplementing <PersistentEngine>();

            if (persistentEngine is null)
            {
                return(null);
            }

            // find ProtoPartModuleSnapshot and moduleIndex
            int moduleIndex;
            ProtoPartModuleSnapshot persistentEngineModuleSnapshot = null;

            for (moduleIndex = 0; moduleIndex < protoPartSnapshot.modules.Count; moduleIndex++)
            {
                persistentEngineModuleSnapshot = protoPartSnapshot.modules[moduleIndex];
                if (persistentEngineModuleSnapshot.moduleName == nameof(PersistentEngine))
                {
                    break;
                }
            }

            if (persistentEngineModuleSnapshot == null)
            {
                return(null);
            }

            var engineData = new PersistentEngineData
            {
                PartIndex               = partIndex,
                ModuleIndex             = moduleIndex,
                ProtoPart               = protoPart,
                ProtoPartSnapshot       = protoPartSnapshot,
                PersistentPartId        = protoPartSnapshot.persistentId,
                ProtoPartModuleSnapshot = persistentEngineModuleSnapshot,
                PersistentEngine        = persistentEngine
            };

            // store data
            vesselData.Engines.Add(protoPartSnapshot.persistentId, engineData);

            // Load persistentThrust from ProtoPartModuleSnapshots
            persistentEngineModuleSnapshot.moduleValues.TryGetValue(nameof(persistentEngine.persistentThrust),
                                                                    ref persistentEngine.persistentThrust);

            var moduleEngines = protoPart.FindModulesImplementing <ModuleEngines>();

            if (moduleEngines == null || moduleEngines.Any() == false)
            {
                return(null);
            }

            // collect propellant configurations
            var persistentEngineModules = new List <PersistentEngineModule>();

            foreach (var moduleEngine in moduleEngines)
            {
                engineData.MaxThrust += moduleEngine.maxThrust;

                List <PersistentPropellant> persistentPropellants = PersistentPropellant.MakeList(moduleEngine.propellants);

                var persistentEngineModule = new PersistentEngineModule
                {
                    propellants    = persistentPropellants,
                    averageDensity = persistentPropellants.AverageDensity()
                };
                persistentEngineModules.Add(persistentEngineModule);
            }

            persistentEngine.moduleEngines = persistentEngineModules.ToArray();

            // check if there any active persistent engines that need to be processed
            if (persistentEngine.persistentThrust > 0)
            {
                vesselData.HasAnyActivePersistentEngine = true;
            }
            else
            {
                return(null);
            }

            return(engineData);
        }