private void SetGeneratorInfo() { var moduleGenerator = PartExtensions.GetModule <ModuleGenerator>(selectedPart); if (moduleGenerator != null) { if (moduleGenerator.resHandler.inputResources.Count > 0) { infoItems.Add(PartInfoItem.Create("Generator Input")); for (int i = 0; i < moduleGenerator.resHandler.inputResources.Count; ++i) { var generatorResource = moduleGenerator.resHandler.inputResources[i]; infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate())); } } if (moduleGenerator.resHandler.outputResources.Count > 0) { infoItems.Add(PartInfoItem.Create("Generator Output")); for (int i = 0; i < moduleGenerator.resHandler.outputResources.Count; ++i) { var generatorResource = moduleGenerator.resHandler.outputResources[i]; infoItems.Add(PartInfoItem.Create("\t" + generatorResource.name, generatorResource.rate.ToRate())); } } if (moduleGenerator.isAlwaysActive) { infoItems.Add(PartInfoItem.Create("Generator is Always Active")); } } }
private void SetGimbalInfo() { var moduleGimbal = PartExtensions.GetModule <ModuleGimbal>(selectedPart); if (moduleGimbal != null) { infoItems.Add(PartInfoItem.Create("Thrust Vectoring", moduleGimbal.gimbalRange.ToString("F2"))); } }
private void SetRcsInfo() { var moduleRcs = PartExtensions.GetModule <ModuleRCS>(selectedPart); if (moduleRcs != null) { infoItems.Add(PartInfoItem.Create("Thruster Power", moduleRcs.thrusterPower.ToForce())); infoItems.Add(PartInfoItem.Create("Specific Impulse", Units.ConcatF(moduleRcs.atmosphereCurve.Evaluate(1.0f), moduleRcs.atmosphereCurve.Evaluate(0.0f)) + "s")); } }
private void SetParachuteInfo() { var moduleParachute = PartExtensions.GetModule <ModuleParachute>(selectedPart); if (moduleParachute != null) { infoItems.Add(PartInfoItem.Create("Deployed Drag", Units.ConcatF(moduleParachute.semiDeployedDrag, moduleParachute.fullyDeployedDrag))); infoItems.Add(PartInfoItem.Create("Deployment Altitude", moduleParachute.deployAltitude.ToDistance())); infoItems.Add(PartInfoItem.Create("Deployment Pressure", moduleParachute.minAirPressureToOpen.ToString("F2"))); } }
private void SetTransmitterInfo() { var moduleDataTransmitter = PartExtensions.GetModule <ModuleDataTransmitter>(selectedPart); if (moduleDataTransmitter != null) { infoItems.Add(PartInfoItem.Create("Packet Size", moduleDataTransmitter.packetSize.ToString("F2") + " Mits")); infoItems.Add(PartInfoItem.Create("Bandwidth", (moduleDataTransmitter.packetInterval * moduleDataTransmitter.packetSize).ToString("F2") + "Mits/sec")); // TODO: allow for multiple consumed resources infoItems.Add(PartInfoItem.Create(moduleDataTransmitter.GetConsumedResources()[0].name, moduleDataTransmitter.packetResourceCost.ToString("F2") + "/Packet")); } }
private void SetScienceExperimentInfo() { var moduleScienceExperiment = PartExtensions.GetModule <ModuleScienceExperiment>(selectedPart); if (moduleScienceExperiment != null) { infoItems.Add(PartInfoItem.Create("Science Experiment", moduleScienceExperiment.experimentActionName)); infoItems.Add(PartInfoItem.Create("\tTransmit Efficiency", moduleScienceExperiment.xmitDataScalar.ToPercent())); if (moduleScienceExperiment.rerunnable == false) { infoItems.Add(PartInfoItem.Create("\tSingle Usage")); } } }
private void SetAlternatorInfo() { ModuleAlternator moduleAlternator = PartExtensions.GetModule <ModuleAlternator>(selectedPart); if (moduleAlternator != null) { infoItems.Add(PartInfoItem.Create("Alternator")); for (int i = 0; i < moduleAlternator.resHandler.outputResources.Count; ++i) { var moduleResource = moduleAlternator.resHandler.outputResources[i]; infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate())); } } }
private static bool IsEnginePlate(Part thePart) { ModuleDecouple mdec = PartExtensions.GetModule <ModuleDecouple>(thePart); if (mdec != null && mdec.IsStageable()) { ModuleDynamicNodes mdyn = PartExtensions.GetModule <ModuleDynamicNodes>(thePart); if (mdyn != null) { return(true); } } return(false); }
private void SetReactionWheelInfo() { var moduleReactionWheel = PartExtensions.GetModule <ModuleReactionWheel>(selectedPart); if (moduleReactionWheel != null) { infoItems.Add(PartInfoItem.Create("Reaction Wheel Torque")); infoItems.Add(PartInfoItem.Create("\tPitch", moduleReactionWheel.PitchTorque.ToTorque())); infoItems.Add(PartInfoItem.Create("\tRoll", moduleReactionWheel.RollTorque.ToTorque())); infoItems.Add(PartInfoItem.Create("\tYaw", moduleReactionWheel.YawTorque.ToTorque())); for (int i = 0; i < moduleReactionWheel.resHandler.inputResources.Count; ++i) { var moduleResource = moduleReactionWheel.resHandler.inputResources[i]; infoItems.Add(PartInfoItem.Create("\t" + moduleResource.name, moduleResource.rate.ToRate())); } } }
private void SetSolarPanelInfo() { var moduleDeployableSolarPanel = PartExtensions.GetModule <ModuleDeployableSolarPanel>(selectedPart); if (moduleDeployableSolarPanel != null) { infoItems.Add(PartInfoItem.Create("Charge Rate", moduleDeployableSolarPanel.chargeRate.ToRate())); if (moduleDeployableSolarPanel.isBreakable) { infoItems.Add(PartInfoItem.Create("Breakable")); } if (moduleDeployableSolarPanel.trackingBody == Sun.Instance) { infoItems.Add(PartInfoItem.Create("Sun Tracking")); } } }
// This function prepares the simulation by creating all the necessary data structures it will // need during the simulation. All required data is copied from the core game data structures // so that the simulation itself can be run in a background thread without having issues with // the core game changing the data while the simulation is running. public bool PrepareSimulation(LogMsg _log, List <Part> parts, double theGravity, double theAtmosphere = 0, double theMach = 0, bool dumpTree = false, bool vectoredThrust = false, bool fullThrust = false) { log = _log; if (log != null) { log.AppendLine("PrepareSimulation started"); } _timer.Reset(); _timer.Start(); // Store the parameters in members for ease of access in other functions partList = parts; gravity = theGravity; atmosphere = theAtmosphere; mach = theMach; lastStage = StageManager.LastStage; maxMach = 1.0f; if (log != null) { log.AppendLine("lastStage = ", lastStage); } // Clear the lists for our simulation parts allParts.Clear(); allFuelLines.Clear(); drainingParts.Clear(); allEngines.Clear(); activeEngines.Clear(); drainingResources.Clear(); // A dictionary for fast lookup of Part->PartSim during the preparation phase partSimLookup.Clear(); if (partList.Count > 0 && partList[0].vessel != null) { vesselName = partList[0].vessel.vesselName; vesselType = partList[0].vessel.vesselType; } // First we create a PartSim for each Part (giving each a unique id) int partId = 1; for (int i = 0; i < partList.Count; ++i) { Part part = partList[i]; // If the part is already in the lookup dictionary then log it and skip to the next part if (partSimLookup.ContainsKey(part)) { if (log != null) { log.AppendLine("Part ", part.name, " appears in vessel list more than once"); } continue; } // Create the PartSim PartSim partSim = PartSim.New(part, partId, atmosphere, log); // Add it to the Part lookup dictionary and the necessary lists partSimLookup.Add(part, partSim); allParts.Add(partSim); if (partSim.isFuelLine) { allFuelLines.Add(partSim); } if (partSim.isEngine) { partSim.CreateEngineSims(allEngines, atmosphere, mach, vectoredThrust, fullThrust, log); } if (partSim.isRCS) { partSim.CreateRCSSims(allRCS, atmosphere, mach, vectoredThrust, fullThrust, log); } partId++; } for (int i = 0; i < allEngines.Count; ++i) { maxMach = Mathf.Max(maxMach, allEngines[i].maxMach); } UpdateActiveEngines(); // Now that all the PartSims have been created we can do any set up that needs access to other parts // First we set up all the parent links for (int i = 0; i < allParts.Count; i++) { PartSim partSim = allParts[i]; partSim.SetupParent(partSimLookup, log); } // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets if (HighLogic.LoadedSceneIsEditor) { for (int i = 0; i < allFuelLines.Count; ++i) { PartSim partSim = allFuelLines[i]; CModuleFuelLine fuelLine = PartExtensions.GetModule <CModuleFuelLine>(partSim.part); if (fuelLine.target != null) { PartSim targetSim; if (partSimLookup.TryGetValue(fuelLine.target, out targetSim)) { if (log != null) { log.AppendLine("Fuel line target is ", targetSim.name, ":", targetSim.partId); } targetSim.fuelTargets.Add(partSim.parent); } else { if (log != null) { log.AppendLine("No PartSim for fuel line target (", partSim.part.partInfo.name, ")"); } } } else { if (log != null) { log.AppendLine("Fuel line target is null"); } } } } if (log != null) { log.AppendLine("SetupAttachNodes and count stages"); } for (int i = 0; i < allParts.Count; ++i) { PartSim partSim = allParts[i]; partSim.SetupAttachNodes(partSimLookup, log); if (partSim.decoupledInStage >= lastStage) { lastStage = partSim.decoupledInStage + 1; } } // And finally release the Part references from all the PartSims if (log != null) { log.AppendLine("ReleaseParts"); } for (int i = 0; i < allParts.Count; ++i) { allParts[i].ReleasePart(); } // And dereference the core's part list partList = null; _timer.Stop(); if (log != null) { log.AppendLine("PrepareSimulation: ", _timer.ElapsedMilliseconds, "ms"); log.Flush(); } Dump(); log = null; return(true); }
private int DecoupledInStage(Part thePart) { int stage = -1; Part original = thePart; if (original.parent == null) { return(stage); //root part is always present. Fixes phantom stage if root is stageable. } chain.Clear(); while (thePart != null) { chain.Add(thePart); if (thePart.inverseStage > stage) { ModuleDecouple mdec = PartExtensions.GetModule <ModuleDecouple>(thePart); ModuleDockingNode mdock = PartExtensions.GetModule <ModuleDockingNode>(thePart); ModuleAnchoredDecoupler manch = PartExtensions.GetModule <ModuleAnchoredDecoupler>(thePart); if (mdec != null) { AttachNode att = thePart.FindAttachNode(mdec.explosiveNodeID); if (mdec.isOmniDecoupler) { stage = thePart.inverseStage; } else { if (att != null) { if ((thePart.parent != null && att.attachedPart == thePart.parent) || PartExtensions.ContainedPart(att.attachedPart, chain)) { stage = thePart.inverseStage; } } else { stage = thePart.inverseStage; } } } if (manch != null) //radial decouplers (ALSO REENTRY PODS BECAUSE REASONS!) { AttachNode att = thePart.FindAttachNode(manch.explosiveNodeID); // these stupid fuckers don't initialize in the Editor scene. if (att != null) { if ((thePart.parent != null && att.attachedPart == thePart.parent) || PartExtensions.ContainedPart(att.attachedPart, chain)) { stage = thePart.inverseStage; } } else { stage = thePart.inverseStage; //radial decouplers it seems the attach node ('surface') comes back null. } } if (mdock != null) //docking port { if (original == thePart) //checking self, never leaves. { } else { stage = thePart.inverseStage; } } } thePart = thePart.parent; } return(stage); }