private static void LoadUnloadedPart(int partIndex, ProtoPartSnapshot protoPartSnapshot, VesselData vesselData) { LoadTweakScalePartModules(protoPartSnapshot, vesselData); Part protoPart = PartLoader.getPartInfoByName(protoPartSnapshot.partName)?.partPrefab; if (protoPart == null) { return; } LoadModuleDeployableSolarPanel(partIndex, protoPartSnapshot, vesselData, protoPart); LoadModuleGenerator(partIndex, protoPartSnapshot, vesselData, protoPart); LoadModuleResourceConverters(partIndex, protoPartSnapshot, vesselData, protoPart); EngineBackgroundProcessing.LoadPersistentEngine(partIndex, protoPartSnapshot, vesselData, protoPart); }
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; } }
void FixedUpdate() { // store info for oldest unloaded vessel double last_time = 0.0; VesselData last_vd = null; UniversalTime = Planetarium.GetUniversalTime(); foreach (Vessel vessel in FlightGlobals.Vessels) { // don't process a vessel until unloaded, but add it to vesselDataDict if (vessel.loaded) { if (!VesselDataDict.ContainsKey(vessel.id)) { VesselDataDict.Add(vessel.id, new VesselData(vessel)); } continue; } // ignore Kerbals if (vessel.isEVA) { continue; } // ignore irrelevant vessel types if (vessel.vesselType == VesselType.Debris || vessel.vesselType == VesselType.Flag || vessel.vesselType == VesselType.SpaceObject || vessel.vesselType == VesselType.DeployedSciencePart || vessel.vesselType == VesselType.DeployedScienceController ) { continue; } // lookup cashed vessel data if (!VesselDataDict.TryGetValue(vessel.id, out VesselData vesselData)) { vesselData = new VesselData(vessel); VesselDataDict.Add(vessel.id, vesselData); } else { vesselData.Vessel = vessel; } vesselData.Time += TimeWarp.fixedDeltaTime; // maintain oldest entry if (vesselData.Time > last_time) { last_time = vesselData.Time; last_vd = vesselData; } // determine available resources and total vessel mass UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.UpdateUnloadedVesselData"); vesselData.UpdateUnloadedVesselData(); UnityEngine.Profiling.Profiler.EndSample(); } // at most one vessel gets background processing per physics tick : // if there is a vessel that is not the currently loaded vessel, then // we will update the vessel whose most recent background update is the oldest if (last_vd != null) { last_vd.DeltaTime = last_time; // look for relevant modules in all vessel parts UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.LoadUnloadedParts"); LoadUnloadedParts(last_vd); UnityEngine.Profiling.Profiler.EndSample(); // extract resources from Solar Panels UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.ProcessUnloadedSolarPanels"); ProcessUnloadedSolarPanels(last_vd); UnityEngine.Profiling.Profiler.EndSample(); // extract resources from generators (RTG etc) UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.ProcessUnloadedModuleGenerators"); ProcessUnloadedModuleGenerators(last_vd, last_time); UnityEngine.Profiling.Profiler.EndSample(); // extract resources from generators (Fuel Cells etc) UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.ProcessUnloadedResourceConverters"); ProcessUnloadedResourceConverters(last_vd, last_time); UnityEngine.Profiling.Profiler.EndSample(); // process persistent engines UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.ProcessUnloadedPersistentEngines"); EngineBackgroundProcessing.ProcessUnloadedPersistentEngines(last_vd, last_time); UnityEngine.Profiling.Profiler.EndSample(); // update resources on vessel UnityEngine.Profiling.Profiler.BeginSample("PersistentThrust.PersistentScenarioModule.FixedUpdate.UpdatePersistentResources"); UpdatePersistentResources(last_vd, last_time); UnityEngine.Profiling.Profiler.EndSample(); last_vd.Time = 0.0; } }