public Add ( int type, double amount ) : void | ||
type | int | |
amount | double | |
return | void |
private void SetResourceDrainRateRecursive(int type, double amount, List <PartSim> visited = null) { if (visited == null) { visited = new List <PartSim>(); } List <PartSim> newVisited = new List <PartSim>(visited); newVisited.Add(this); List <PartSim> fuelLines = new List <PartSim>(); foreach (PartSim partSim in sourceParts) { if (partSim.part is FuelLine && !visited.Contains(partSim)) { if (partSim.CanSupplyResourceRecursive(type, newVisited)) { fuelLines.Add(partSim); } } } if (fuelLines.Count > 0) { foreach (PartSim fuelLine in fuelLines) { fuelLine.SetResourceDrainRateRecursive(type, amount / fuelLines.Count, newVisited); } return; } foreach (PartSim partSim in sourceParts) { if (!visited.Contains(partSim) && partSim.CanSupplyResourceRecursive(type, newVisited)) { if (DrainFromSourceBeforeSelf(type, partSim)) { partSim.SetResourceDrainRateRecursive(type, amount, newVisited); return; } } } if (this.resources[type] > 0) { resourceDrains.Add(type, amount); } }
public PartSim(Part thePart, int id, double atmosphere, LogMsg log) { part = thePart; partId = id; name = part.partInfo.name; if (log != null) { log.buf.AppendLine("Create PartSim for " + name); } parent = null; fuelCrossFeed = part.fuelCrossFeed; noCrossFeedNodeKey = part.NoCrossFeedNodeKey; decoupledInStage = DecoupledInStage(part); isFuelLine = part is FuelLine; isFuelTank = part is FuelTank; isSepratron = IsSepratron(); inverseStage = part.inverseStage; //MonoBehaviour.print("inverseStage = " + inverseStage); cost = part.partInfo.cost; foreach (PartResource resource in part.Resources) { cost -= (float)((resource.maxAmount - resource.amount) * resource.info.unitCost); } // Work out if the part should have no physical significance isNoPhysics = part.HasModule <ModuleLandingGear>() || part.HasModule <LaunchClamp>() || part.physicalSignificance == Part.PhysicalSignificance.NONE || part.PhysicsSignificance == 1; if (!isNoPhysics) { baseMass = part.mass; } if (SimManager.logOutput) { MonoBehaviour.print((isNoPhysics ? "Ignoring" : "Using") + " part.mass of " + part.mass); } foreach (PartResource resource in part.Resources) { // Make sure it isn't NaN as this messes up the part mass and hence most of the values // This can happen if a resource capacity is 0 and tweakable if (!Double.IsNaN(resource.amount)) { if (SimManager.logOutput) { MonoBehaviour.print(resource.resourceName + " = " + resource.amount); } resources.Add(resource.info.id, resource.amount); resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0); } else { MonoBehaviour.print(resource.resourceName + " is NaN. Skipping."); } } startMass = GetMass(); hasVessel = (part.vessel != null); isLanded = hasVessel && part.vessel.Landed; if (hasVessel) { vesselName = part.vessel.vesselName; vesselType = part.vesselType; } initialVesselName = part.initialVesselName; hasMultiModeEngine = part.HasModule <MultiModeEngine>(); hasModuleEnginesFX = part.HasModule <ModuleEnginesFX>(); hasModuleEngines = part.HasModule <ModuleEngines>(); isEngine = hasMultiModeEngine || hasModuleEnginesFX || hasModuleEngines; if (SimManager.logOutput) { MonoBehaviour.print("Created " + name + ". Decoupled in stage " + decoupledInStage); } }
public void SetResourceConsumptions() { if (this.part.HasModule <MultiModeEngine>()) { string mode = this.part.GetModule <MultiModeEngine>().mode; foreach (ModuleEnginesFX engine in this.part.GetModules <ModuleEnginesFX>()) { if (engine.engineID == mode) { double flowRate = 0d; if (part.vessel != null) { if (engine.throttleLocked) { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } else { if (part.vessel.Landed) { flowRate = Math.Max(0.000001d, engine.maxThrust * (engine.thrustPercentage / 100f) * FlightInputHandler.state.mainThrottle) / (isp * 9.81d); } else { if (engine.requestedThrust > 0) { flowRate = engine.requestedThrust / (isp * 9.81d); } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } } } } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } float flowMass = 0f; foreach (Propellant propellant in engine.propellants) { flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id); } foreach (Propellant propellant in engine.propellants) { if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir") { continue; } double consumptionRate = propellant.ratio * flowRate / flowMass; resourceConsumptions.Add(propellant.id, consumptionRate); } } } } else if (this.part.HasModule <ModuleEnginesFX>()) { foreach (ModuleEnginesFX engine in part.GetModules <ModuleEnginesFX>()) { double flowRate = 0d; if (part.vessel != null) { if (engine.throttleLocked) { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } else { if (part.vessel.Landed) { flowRate = Math.Max(0.000001d, engine.maxThrust * (engine.thrustPercentage / 100f) * FlightInputHandler.state.mainThrottle) / (isp * 9.81d); } else { if (engine.requestedThrust > 0) { flowRate = engine.requestedThrust / (isp * 9.81d); } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } } } } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } float flowMass = 0f; foreach (Propellant propellant in engine.propellants) { flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id); } foreach (Propellant propellant in engine.propellants) { if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir") { continue; } double consumptionRate = propellant.ratio * flowRate / flowMass; resourceConsumptions.Add(propellant.id, consumptionRate); } } } else if (this.part.HasModule <ModuleEngines>()) { foreach (ModuleEngines engine in part.GetModules <ModuleEngines>()) { double flowRate = 0d; if (part.vessel != null) { if (engine.throttleLocked) { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } else { if (part.vessel.Landed) { flowRate = Math.Max(0.000001d, engine.maxThrust * (engine.thrustPercentage / 100f) * FlightInputHandler.state.mainThrottle) / (isp * 9.81d); } else { if (engine.requestedThrust > 0) { flowRate = engine.requestedThrust / (isp * 9.81d); } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } } } } else { flowRate = engine.maxThrust * (engine.thrustPercentage / 100f) / (isp * 9.81d); } float flowMass = 0f; foreach (Propellant propellant in engine.propellants) { flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id); } foreach (Propellant propellant in engine.propellants) { if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir") { continue; } double consumptionRate = propellant.ratio * flowRate / flowMass; resourceConsumptions.Add(propellant.id, consumptionRate); } } } }
public PartSim(Part part, double atmosphere) { this.part = part; foreach (PartResource resource in part.Resources) { resources.Add(resource.info.id, resource.amount); } if (this.part.HasModule <MultiModeEngine>()) { string mode = this.part.GetModule <MultiModeEngine>().mode; foreach (ModuleEnginesFX engine in this.part.GetModules <ModuleEnginesFX>()) { if (engine.engineID == mode) { if (part.vessel != null) { actualThrust = engine.requestedThrust; isp = engine.atmosphereCurve.Evaluate((float)part.staticPressureAtm); } else { isp = engine.atmosphereCurve.Evaluate((float)atmosphere); } thrust = engine.maxThrust * (engine.thrustPercentage / 100f); } } } else if (this.part.HasModule <ModuleEnginesFX>()) { foreach (ModuleEnginesFX engine in this.part.GetModules <ModuleEnginesFX>()) { if (part.vessel != null) { actualThrust = engine.requestedThrust; isp = engine.atmosphereCurve.Evaluate((float)part.staticPressureAtm); } else { isp = engine.atmosphereCurve.Evaluate((float)atmosphere); } thrust = engine.maxThrust * (engine.thrustPercentage / 100f); } } else if (this.part.HasModule <ModuleEngines>()) { foreach (ModuleEngines engine in this.part.GetModules <ModuleEngines>()) { if (part.vessel != null) { actualThrust = engine.requestedThrust; isp = engine.atmosphereCurve.Evaluate((float)part.staticPressureAtm); } else { isp = engine.atmosphereCurve.Evaluate((float)atmosphere); } thrust = engine.maxThrust * (engine.thrustPercentage / 100f); } } decoupledInStage = DecoupledInStage(); }
public EngineSim(PartSim theEngine, double atmosphere, double velocity, float maxThrust, float minThrust, float thrustPercentage, float requestedThrust, Vector3 vecThrust, float realIsp, FloatCurve atmosphereCurve, FloatCurve velocityCurve, bool throttleLocked, List <Propellant> propellants, bool active, bool correctThrust) { StringBuilder buffer = null; //MonoBehaviour.print("Create EngineSim for " + theEngine.name); //MonoBehaviour.print("maxThrust = " + maxThrust); //MonoBehaviour.print("minThrust = " + minThrust); //MonoBehaviour.print("thrustPercentage = " + thrustPercentage); //MonoBehaviour.print("requestedThrust = " + requestedThrust); //MonoBehaviour.print("velocity = " + velocity); partSim = theEngine; isActive = active; thrust = (maxThrust - minThrust) * (thrustPercentage / 100f) + minThrust; //MonoBehaviour.print("thrust = " + thrust); thrustVec = vecThrust; double flowRate = 0d; if (partSim.hasVessel) { //MonoBehaviour.print("hasVessel is true"); actualThrust = requestedThrust; if (velocityCurve != null) { actualThrust *= velocityCurve.Evaluate((float)velocity); //MonoBehaviour.print("actualThrust at velocity = " + actualThrust); } isp = atmosphereCurve.Evaluate((float)partSim.part.staticPressureAtm); if (isp == 0d) { MonoBehaviour.print("Isp at " + partSim.part.staticPressureAtm + " is zero. Flow rate will be NaN"); } if (correctThrust && realIsp == 0) { float ispsl = atmosphereCurve.Evaluate(0); if (ispsl != 0) { thrust = thrust * isp / ispsl; } else { MonoBehaviour.print("Isp at sea level is zero. Unable to correct thrust."); } //MonoBehaviour.print("corrected thrust = " + thrust); } if (velocityCurve != null) { thrust *= velocityCurve.Evaluate((float)velocity); //MonoBehaviour.print("thrust at velocity = " + thrust); } if (throttleLocked) { //MonoBehaviour.print("throttleLocked is true"); flowRate = thrust / (isp * 9.81d); } else { if (partSim.isLanded) { //MonoBehaviour.print("partSim.isLanded is true, mainThrottle = " + FlightInputHandler.state.mainThrottle); flowRate = Math.Max(0.000001d, thrust * FlightInputHandler.state.mainThrottle) / (isp * 9.81d); } else { if (requestedThrust > 0) { if (velocityCurve != null) { requestedThrust *= velocityCurve.Evaluate((float)velocity); //MonoBehaviour.print("requestedThrust at velocity = " + requestedThrust); } //MonoBehaviour.print("requestedThrust > 0"); flowRate = requestedThrust / (isp * 9.81d); } else { //MonoBehaviour.print("requestedThrust <= 0"); flowRate = thrust / (isp * 9.81d); } } } } else { //MonoBehaviour.print("hasVessel is false"); isp = atmosphereCurve.Evaluate((float)atmosphere); if (isp == 0d) { MonoBehaviour.print("Isp at " + atmosphere + " is zero. Flow rate will be NaN"); } if (correctThrust) { float ispsl = atmosphereCurve.Evaluate(0); if (ispsl != 0) { thrust = thrust * isp / ispsl; } else { MonoBehaviour.print("Isp at sea level is zero. Unable to correct thrust."); } //MonoBehaviour.print("corrected thrust = " + thrust); } if (velocityCurve != null) { thrust *= velocityCurve.Evaluate((float)velocity); //MonoBehaviour.print("thrust at velocity = " + thrust); } flowRate = thrust / (isp * 9.81d); } if (SimManager.logOutput) { buffer = new StringBuilder(1024); buffer.AppendFormat("flowRate = {0:g6}\n", flowRate); } float flowMass = 0f; foreach (Propellant propellant in propellants) { flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id); } if (SimManager.logOutput) { buffer.AppendFormat("flowMass = {0:g6}\n", flowMass); } foreach (Propellant propellant in propellants) { if (propellant.name == "ElectricCharge" || propellant.name == "IntakeAir") { continue; } double consumptionRate = propellant.ratio * flowRate / flowMass; if (SimManager.logOutput) { buffer.AppendFormat("Add consumption({0}, {1}:{2:d}) = {3:g6}\n", ResourceContainer.GetResourceName(propellant.id), theEngine.name, theEngine.partId, consumptionRate); } resourceConsumptions.Add(propellant.id, consumptionRate); } if (SimManager.logOutput) { MonoBehaviour.print(buffer); } }