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); } } }
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); }