/// <summary> /// This method is used to apply a particular failure mode. Mostly it's used internally, but it's exposed as a public method for diagnistic purposes. /// </summary> /// <param name="mode">A BARISEngineFailureModes enumerator containing the failure mode to process.</param> public void ApplyFailureMode(BARRISEngineFailureModes mode = BARRISEngineFailureModes.None) { //Make sure we have the active engine. getCurrentEngine(); switch (mode) { case BARRISEngineFailureModes.StuckOn: engine.allowShutdown = false; engine.currentThrottle = 1.0f; engine.finalThrust = engine.maxThrust; engine.throttleLocked = true; break; case BARRISEngineFailureModes.Shutdown: if (EngineIsRunning) { engine.Shutdown(); engine.currentThrottle = 0; } break; case BARRISEngineFailureModes.ReducedThrust: engine.currentThrottle = failureThrustPercent; engine.finalThrust *= failureThrustPercent; break; default: break; } }
virtual internal void shutdown() { if (engine.allowShutdown) { engine.Shutdown(); } else { ventFuel(); engine.allowShutdown = true; engine.Shutdown(); engine.allowShutdown = false; } }
private void disable(ModuleEngines m) { m.Shutdown(); m.DeactivateRunningFX(); m.DeactivatePowerFX(); m.enabled = false; }
private void RemoveMasslessPropellantsFromEngine(List <PersistentPropellant> pplist) { var akPropellants = new ConfigNode(); //Get the Ignition state, i.e. is the engine shutdown or activated var ignitionState = engine.getIgnitionState; engine.Shutdown(); foreach (var propellant in pplist) { if (propellant.density == 0) { continue; } var propellantConfig = LoadPropellant(propellant.propellant.name, propellant.propellant.ratio); akPropellants.AddNode(propellantConfig); } engine.Load(akPropellants); if (ignitionState) { engine.Activate(); } }
public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight) { return; } try { pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.functional).Sum(prc => prc.area); intakes_open_area = vessel.FindPartModulesImplementing <AtmosphericIntake>().Where(mre => mre.intakeOpen).Sum(mre => mre.area); missingPrecoolerRatio = intakes_open_area > 0 ? Math.Min(1, Math.Max(0, Math.Pow((intakes_open_area - pre_coolers_active) / intakes_open_area, missingPrecoolerProportionExponent))) : 0; missingPrecoolerRatio = missingPrecoolerRatio.IsInfinityOrNaN() ? 1 : missingPrecoolerRatio; if (rapier_engine != null) { if (rapier_engine.isOperational && rapier_engine.currentThrottle > 0 && rapier_engine.useVelCurve) { temp1 = Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 10.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * missingPrecoolerRatio, 1); if (temp1 >= (part.maxTemp - 10)) { ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER); rapier_engine.Shutdown(); part.temperature = 1; return; } part.temperature = temp1; } else { part.temperature = 1; } } if (rapier_engine2 != null) { if (rapier_engine2.isOperational && rapier_engine2.currentThrottle > 0 && rapier_engine2.useVelCurve) { temp2 = Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * missingPrecoolerRatio, 1); if (temp2 >= (part.maxTemp - 10)) { ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER); rapier_engine2.Shutdown(); part.temperature = 1; return; } part.temperature = temp2; } else { part.temperature = 1; } } } catch (Exception ex) { Debug.Log("[KSPI]: ModuleSabreHeating threw Exception in FixedUpdate(): " + ex); } }
internal override void Toggle() { if (GetState()) { if (engineModule.allowShutdown && (action == ActionType.Toggle || action == ActionType.Deactivate)) { engineModule.Shutdown(); } } else { if (/*engineModule.allowRestart &&*/ (action == ActionType.Toggle || action == ActionType.Activate)) { engineModule.Activate(); } } }
public void FixedUpdate() { if (HighLogic.LoadedSceneIsFlight) { try { pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.isFunctional()).Count(); intakes_open = vessel.FindPartModulesImplementing <ModuleResourceIntake>().Where(mre => mre.intakeEnabled).Count(); double proportion = Math.Pow((double)(intakes_open - pre_coolers_active) / (double)intakes_open, 0.1); proportion = (!double.IsNaN(proportion) && !double.IsInfinity(proportion)) ? proportion : 1; if (rapier_engine != null) { if (rapier_engine.isOperational && rapier_engine.currentThrottle > 0 && rapier_engine.useVelCurve) { double temp = Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 10.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1); if (temp >= (part.maxTemp - 10.0f)) { ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER); rapier_engine.Shutdown(); part.temperature = 1; return; } part.temperature = temp; } else { part.temperature = 1; } } if (rapier_engine2 != null) { if (rapier_engine2.isOperational && rapier_engine2.currentThrottle > 0 && rapier_engine2.useVelCurve) { double temp = Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1); if (temp >= (part.maxTemp - 10.0f)) { ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER); rapier_engine2.Shutdown(); part.temperature = 1; return; } part.temperature = temp; } else { part.temperature = 1; } } } catch (Exception ex) { Debug.Log("[KSPI] - ModuleSabreHeating threw Exception in OnFixedUpdate(): " + ex); } } }
public override void OnUpdate() { if (!engineIsFX) { engineIsOn = modEng.EngineIgnited; } else { engineIsOn = modEngFX.EngineIgnited; } foreach (var anim in engineStates) { if (engineIsOn && anim.normalizedTime < WaitForAnimation) { anim.speed = 1; if (engineIsFX) { modEngFX.Shutdown(); } else { modEng.Shutdown(); } } if (anim.normalizedTime >= WaitForAnimation && anim.speed > 0) { if (engineIsFX) { modEngFX.Activate(); } else { modEng.Activate(); } } if (anim.normalizedTime >= 1) { anim.speed = 0; anim.normalizedTime = 1; } if (anim.normalizedTime >= 1 && !engineIsOn) { anim.speed = -1; } if (anim.normalizedTime < 0) { anim.speed = 0; anim.normalizedTime = 0; } } }
/// <summary> /// Toggles all of the engines in the selected group that can be toggled /// (activates them if they're deactivated, shuts them off if they're active). /// /// Note that, unlike the core `fc` version of this method, it is possible /// to activate engines that are not in the current stage using this method. /// </summary> /// <param name="groupId">A number from 1 to 31 (inclusive) to select a specific group, or 0 to select all groups.</param> /// <param name="newState">When true, activates engines in the group. When false, deactivates them.</param> /// <returns>1 if any engines were toggled, 0 otherwise.</returns> public double SetEnginesEnabled(double groupId, bool newState) { int id = (int)groupId; double anyChanged = 0.0; if (id == 0) { for (int i = 0; i < vc.engineGroup.Length; ++i) { ModuleEngines me = vc.engineGroup[i].engine; Part thatPart = me.part; if (thatPart.inverseStage == StageManager.CurrentStage || !newState) { if (me.EngineIgnited != newState) { if (newState && me.allowRestart) { me.Activate(); anyChanged = 1.0; } else if (me.allowShutdown) { me.Shutdown(); anyChanged = 1.0; } } } } } else { for (int i = 0; i < vc.engineGroup.Length; ++i) { if (vc.engineGroup[i].partId == id) { ModuleEngines me = vc.engineGroup[i].engine; if (me.EngineIgnited != newState) { if (newState && me.allowRestart) { me.Activate(); anyChanged = 1.0; } else if (me.allowShutdown) { me.Shutdown(); anyChanged = 1.0; } } } } } return(anyChanged); }
public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight || vessel.HoldPhysics) { return; } if (_escapeEngine != null && _escapeEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - _escapeEngineStartTime >= escapeEngineRunTime) { _escapeEngine.Shutdown(); } if (hasPitchControl) { // in real life, the LES had a huge chunk of depleted uranium ballast in its nosecone // in the game, when we model the LES using a single part the center of mass shifts // too far aft as solid fuel is burned, compared to real life. This makes it // difficult to maintain stable flight // while the escape engine is running, adjust the center of mass offset var comFactor = (_maxFuel - part.Resources["SolidFuel"].amount) / comMult; var newComY = _origComOffset.y + (float)comFactor; part.CoMOffset.Set(_origComOffset.x, newComY, _origComOffset.z); } } if (_pitchEngine != null && _pitchEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - _pitchEngineStartTime >= pitchEngineRunTime) { _pitchEngine.Shutdown(); } } if (_jettisonEngine != null && _jettisonEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - _jettisonEngineStartTime >= jettisonEngineRunTime) { _jettisonEngine.Shutdown(); } } if (hasAborted && hasPitchControl && !hasDeployed && (Planetarium.GetUniversalTime() >= canardDeployTime)) { DeployCanards(); } if (hasAborted && CheckCanAutoJettison()) { Debug.Log(string.Format("{0}: {1}: {2}", _myModTag, part.name, "Calling DoJettison from FixedUpdate()")); DoJettison(); } }
// "Shutdown Engine" public void Shutdown() { if (engineType == EngineModuleType.UNKNOWN) { return; } engine.Shutdown(); engine.DeactivateRunningFX(); engine.DeactivatePowerFX(); }
public void FixedUpdate() { if (aborting) { if (part.Resources["SolidFuel"].amount / part.Resources["SolidFuel"].maxAmount < 0.1) { escapeEngine.Shutdown(); DoJettison(); aborting = false; } } }
// Shutdown engines and override control private void ShutdownEngines() { foreach (Part p in FlightGlobals.ActiveVessel.Parts) { foreach (PartModule pm in p.Modules) { if (!(pm is ModuleEngines)) continue; ModuleEngines eng = (ModuleEngines) pm; if (!(eng.engineType == EngineType.LiquidFuel | eng.engineType == EngineType.Nuclear)) continue; if(!eng.Events["Activate"].active)deactivatedEngines.Add(eng); eng.Shutdown(); eng.Events["Activate"].guiActive = false; } } }
public void Shutdown() { switch (engineType) { case EngineType.Engine: engineModule.Shutdown(); break; case EngineType.EngineFx: engineModuleFx.Shutdown(); break; default: throw new ArgumentOutOfRangeException(); } }
public void Shutdown() { if (engineType == EngineModuleType.UNKNOWN) { return; } if (engineType == EngineModuleType.ENGINE) { engine.Shutdown(); engine.DeactivateRunningFX(); engine.DeactivatePowerFX(); } else { engineFX.Shutdown(); engineFX.DeactivateLoopingFX(); } }
//Part will just shutdown and not be restartable. protected override void FailPart() { if (engine.currentThrottle == 0) { return; } engine.allowShutdown = true; engine.allowRestart = false; engine.Shutdown(); suppressFailure = false; if (!message) { if (vessel.vesselType != VesselType.Debris) { ScreenMessages.PostScreenMessage(part.partInfo.title + " has failed to ignite"); } Debug.Log("[OhScrap]: " + SYP.ID + " has failed to ignite"); postMessage = true; message = true; } }
//Part will just shutdown and not be restartable. public override void FailPart() { if (KRASHWrapper.simulationActive()) { return; } if (engine.currentThrottle == 0) { return; } engine.allowShutdown = true; engine.allowRestart = false; hasFailed = true; engine.Shutdown(); if (!message) { if (vessel.vesselType != VesselType.Debris) { ScreenMessages.PostScreenMessage(part.partInfo.title + " has failed to ignite"); } StringBuilder msg = new StringBuilder(); msg.AppendLine(part.vessel.vesselName); msg.AppendLine(""); msg.AppendLine(part.partInfo.title + " has suffered an " + failureType); msg.AppendLine(""); MessageSystem.Message m = new MessageSystem.Message("OhScrap", msg.ToString(), MessageSystemButton.MessageButtonColor.ORANGE, MessageSystemButton.ButtonIcons.ALERT); MessageSystem.Instance.AddMessage(m); message = true; } if (OhScrap.highlight) { OhScrap.SetFailedHighlight(); } CancelInvoke("FailPart"); Logger.instance.Log("[OhScrap]: " + part.partInfo.title + " has failed to ignite"); }
private bool SetEngineSuffix(string suffixName, object value, ModuleEngines moduleEngines) { switch (suffixName) { case "ACTIVE": var activate = Convert.ToBoolean(value); if (activate) { moduleEngines.Activate(); } else { moduleEngines.Shutdown(); } return(true); case "THRUSTLIMIT": var throttlePercent = (float)Convert.ToDouble(value); moduleEngines.thrustPercentage = throttlePercent; return(true); } return(base.SetSuffix(suffixName, value)); }
//Part will just shutdown and not be restartable. public override void FailPart() { if (engine.currentThrottle == 0) { return; } engine.allowShutdown = true; engine.allowRestart = false; hasFailed = true; engine.Shutdown(); if (!message) { if (vessel.vesselType != VesselType.Debris) { ScreenMessages.PostScreenMessage(part.partInfo.title + " has failed to ignite"); } message = true; } if (OhScrap.highlight) { OhScrap.SetFailedHighlight(); } CancelInvoke("FailPart"); }
public override void OnFixedUpdate() { if (myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0 && myAttachedReactor != null) { if (!myAttachedReactor.IsActive) { myAttachedReactor.enableIfPossible(); } updateIspEngineParams(); float curve_eval_point = (float)Math.Min(FlightGlobals.getStaticPressure(vessel.transform.position), 1.0); float currentIsp = myAttachedEngine.atmosphereCurve.Evaluate(curve_eval_point); double ispratio = currentIsp / maxISP; this.current_isp = currentIsp; // scale down thrust if it's attached to the wrong sized reactor float heat_exchanger_thrust_divisor = 1; if (radius > myAttachedReactor.getRadius()) { heat_exchanger_thrust_divisor = myAttachedReactor.getRadius() * myAttachedReactor.getRadius() / radius / radius; } else { heat_exchanger_thrust_divisor = radius * radius / myAttachedReactor.getRadius() / myAttachedReactor.getRadius(); } if (myAttachedReactor.getRadius() == 0 || radius == 0) { heat_exchanger_thrust_divisor = 1; } // get the flameout safety limit atmospheric_limit = getAtmosphericLimit(); double thrust_limit = myAttachedEngine.thrustPercentage / 100; if (currentpropellant_is_jet) { int pre_coolers_active = vessel.FindPartModulesImplementing <FNModulePreecooler>().Where(prc => prc.isFunctional()).Count(); int intakes_open = vessel.FindPartModulesImplementing <ModuleResourceIntake>().Where(mre => mre.intakeEnabled).Count(); double proportion = Math.Pow((double)(intakes_open - pre_coolers_active) / (double)intakes_open, 0.1); if (double.IsNaN(proportion) || double.IsInfinity(proportion)) { proportion = 1; } float temp = (float)Math.Max((Math.Sqrt(vessel.srf_velocity.magnitude) * 20.0 / GameConstants.atmospheric_non_precooled_limit) * part.maxTemp * proportion, 1); if (temp > part.maxTemp - 10.0f) { ScreenMessages.PostScreenMessage("Engine Shutdown: Catastrophic overheating was imminent!", 5.0f, ScreenMessageStyle.UPPER_CENTER); myAttachedEngine.Shutdown(); part.temperature = 1; } else { part.temperature = temp; } //myAttachedEngine.DeactivateRunningFX(); } else { //myAttachedEngine.ActivateRunningFX(); } double thermal_consume_total = assThermalPower * TimeWarp.fixedDeltaTime * myAttachedEngine.currentThrottle * atmospheric_limit; double thermal_power_received = consumeFNResource(thermal_consume_total, FNResourceManager.FNRESOURCE_THERMALPOWER) / TimeWarp.fixedDeltaTime; if (thermal_power_received * TimeWarp.fixedDeltaTime < thermal_consume_total) { thermal_power_received += consumeFNResource(thermal_consume_total - thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES) / TimeWarp.fixedDeltaTime; } consumeFNResource(thermal_power_received * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT); float power_ratio = 0.0f; double engineMaxThrust = 0.01; if (assThermalPower > 0) { power_ratio = (float)(thermal_power_received / assThermalPower); engineMaxThrust = Math.Max(thrust_limit * 2000.0 * thermal_power_received / maxISP / g0 * heat_exchanger_thrust_divisor * ispratio / myAttachedEngine.currentThrottle, 0.01); } //print ("B: " + engineMaxThrust); // set up TWR limiter if on //double additional_thrust_compensator = myAttachedEngine.finalThrust / (myAttachedEngine.maxThrust * myAttachedEngine.currentThrottle)/ispratio; double engine_thrust = engineMaxThrust / myAttachedEngine.thrustPercentage * 100; // engine thrust fixed //print ("A: " + engine_thrust*myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude)); if (!double.IsInfinity(engine_thrust) && !double.IsNaN(engine_thrust)) { if (isLFO) { myAttachedEngine.maxThrust = (float)(2.2222 * engine_thrust); } else { myAttachedEngine.maxThrust = (float)engine_thrust; } } else { myAttachedEngine.maxThrust = 0.000001f; } // amount of fuel being used at max throttle with no atmospheric limits if (current_isp > 0) { double vcurve_at_current_velocity = 1; if (myAttachedEngine.useVelocityCurve && myAttachedEngine.velocityCurve != null) { vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude); } //if (!double.IsNaN(additional_thrust_compensator) && !double.IsInfinity(additional_thrust_compensator)) { //vcurve_at_current_velocity = additional_thrust_compensator; //} fuel_flow_rate = engine_thrust / current_isp / g0 / 0.005 * TimeWarp.fixedDeltaTime; if (vcurve_at_current_velocity > 0 && !double.IsInfinity(vcurve_at_current_velocity) && !double.IsNaN(vcurve_at_current_velocity)) { fuel_flow_rate = fuel_flow_rate / vcurve_at_current_velocity; } if (atmospheric_limit > 0 && !double.IsInfinity(atmospheric_limit) && !double.IsNaN(atmospheric_limit)) { fuel_flow_rate = fuel_flow_rate / atmospheric_limit; } } } else { if (myAttachedEngine.realIsp > 0) { atmospheric_limit = getAtmosphericLimit(); double vcurve_at_current_velocity = 1; if (myAttachedEngine.useVelocityCurve) { vcurve_at_current_velocity = myAttachedEngine.velocityCurve.Evaluate((float)vessel.srf_velocity.magnitude); } fuel_flow_rate = myAttachedEngine.maxThrust / myAttachedEngine.realIsp / g0 / 0.005 * TimeWarp.fixedDeltaTime; if (vcurve_at_current_velocity > 0 && !double.IsInfinity(vcurve_at_current_velocity) && !double.IsNaN(vcurve_at_current_velocity)) { fuel_flow_rate = fuel_flow_rate / vcurve_at_current_velocity; } } else { fuel_flow_rate = 0; } if (currentpropellant_is_jet) { part.temperature = 1; } if (myAttachedReactor == null && myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0) { myAttachedEngine.Events ["Shutdown"].Invoke(); ScreenMessages.PostScreenMessage("Engine Shutdown: No reactor attached!", 5.0f, ScreenMessageStyle.UPPER_CENTER); } } //tell static helper methods we are currently updating things static_updating = true; static_updating2 = true; }
void FixedUpdate() { //todo: check if vtolengines are attached if (HighLogic.LoadedSceneIsFlight) { vtolEngines = vessel.FindPartModulesImplementing <BDVTOLAnimator>(); } BDVTOLAnimator controllerVTOL = null; foreach (var vtol in vtolEngines) { if (vtol != null) { controllerVTOL = vtol; } } if (controllerVTOL != null) { if (HighLogic.LoadedSceneIsFlight && engine.EngineIgnited != controllerVTOL.part.FindModuleImplementing <ModuleEngines>().EngineIgnited) { if (controllerVTOL.part.FindModuleImplementing <ModuleEngines>().EngineIgnited) { engine.Activate(); } else { engine.Shutdown(); } } float vtolEnginesTorque = 0; foreach (var vtolEngine in vtolEngines) { if (HighLogic.LoadedSceneIsFlight) { vtolEnginesTorque += Mathf.Abs(Mathf.Sin(vtolEngine.currentAngle * Mathf.Deg2Rad) * vtolEngine.part.FindModuleImplementing <ModuleEngines>().finalThrust *Vector3.Distance(vtolEngine.thrustPosition, vessel.findWorldCenterOfMass())); } else { //vtolEnginesTorque += Mathf.Sin(vtolEngine.currentAngle * vtolEngine.part.FindModuleImplementing<ModuleEngines>().maxThrust * Vector3.Distance(vtolEngine.thrustPosition, vessel.findWorldCenterOfMass())); } } if (HighLogic.LoadedSceneIsFlight) { float engineThrust = vtolEnginesTorque / Vector3.Distance(part.FindModelTransform(engine.thrustVectorTransformName).position, vessel.findWorldCenterOfMass()); engine.minThrust = engineThrust; engine.maxThrust = engineThrust; } foreach (var anim in deployStates) { if (controllerVTOL.vtolModeEnabled && anim.normalizedTime < 1) { anim.speed = 1; } else if (controllerVTOL.vtolModeEnabled) { anim.speed = 0; anim.normalizedTime = 1; } else if (anim.normalizedTime > 0) { anim.speed = -1; } else { anim.speed = 0; anim.normalizedTime = 0; } } } }
private bool SetEngineSuffix(string suffixName, object value, ModuleEngines moduleEngines) { switch (suffixName) { case "ACTIVE": var activate = (bool) value; if (activate) { moduleEngines.Activate(); } else { moduleEngines.Shutdown(); } return true; case "THRUSTLIMIT": var throttlePercent = (float) value; moduleEngines.thrustPercentage = throttlePercent; return false; } return base.SetSuffix(suffixName, value); }
public void FixedUpdate() { try { if (!HighLogic.LoadedSceneIsFlight) { return; } if (eModule == null) { SetupDrive(); } if (IsDeployed != eModule.getIgnitionState) { IsDeployed = eModule.getIgnitionState; CheckBubbleDeployment(3); SetPartState(eModule.getIgnitionState); } if (IsDeployed) { //Failsafe if (!CheckAltitude()) { eModule.Shutdown(); return; } //Snip parts DecoupleBubbleParts(); //OH NO FLAMEOUT! if (eModule.flameout) { print("Flameout"); BubbleCollapse(eModule.currentThrottle); FlightInputHandler.state.mainThrottle = 0; IsDeployed = false; return; } PlayWarpAnimation(eModule.currentThrottle); GravityBrake(); //Start by adding in our subluminal speed which is exponential double lowerThrottle = (Math.Min(eModule.currentThrottle, SUBLIGHT_THROTTLE) * SUBLIGHT_MULT); double distance = Math.Pow(lowerThrottle, SUBLIGHT_POWER); //Then if throttle is over our threshold, go linear if (eModule.currentThrottle > SUBLIGHT_THROTTLE) { //How much headroom do we have double maxSpeed = ((LIGHTSPEED * WarpFactor) - distance); //How much of this can we use? var upperThrottle = eModule.currentThrottle - SUBLIGHT_THROTTLE; //How much of this headroom have we used? var throttlePercent = upperThrottle / (1 - SUBLIGHT_THROTTLE); //Add it to our current throttle calculation var additionalDistance = maxSpeed * throttlePercent; distance += additionalDistance; } //Take into acount safe accelleration/decelleration //if (distance > CurrentSpeed + Math.Pow(10,MaxAccelleration)) // distance = CurrentSpeed + Math.Pow(10, MaxAccelleration); //if (distance < CurrentSpeed - Math.Pow(10, MaxAccelleration)) // distance = CurrentSpeed - Math.Pow(10, MaxAccelleration); //CurrentSpeed = distance; //if (distance > 1000) //{ //Let's see if we can get rid of precision issues with distance. // Int32 precision = Math.Round(distance, 0).ToString().Length - 1; // if (precision > MaxAccelleration) precision = MaxAccelleration; // var magnitude = Math.Round((distance / Math.Pow(10, precision)),0); // var jumpDistance = Math.Pow(10,precision) * magnitude; // distance = jumpDistance; //} double maxspeeddisp = Math.Pow(LIGHTSPEED * WarpFactor, GravityBrakes) / LIGHTSPEED; double ts = WarpFactor * (TurboPoint / 100d); if (maxspeeddisp >= ts) { distance = distance / (Math.Log(1 / GravityBrakes) + (1 / (TurboFactor * TurboMult))); maxspeeddisp = maxspeeddisp / (Math.Log(1 / GravityBrakes) + (1 / (TurboFactor * TurboMult))); } if (eModule.currentThrottle > MinThrottle) { // Translate through space on the back of a Kraken! if (maxspeeddisp >= minMaxSpeed) { distance = Math.Pow(distance, GravityBrakes) * TimeWarp.fixedDeltaTime; } else { distance = minMaxSpeed * LIGHTSPEED * TimeWarp.fixedDeltaTime; maxspeeddisp = minMaxSpeed; } Vector3d ps = FlightGlobals.ActiveVessel.transform.position + (transform.up * (float)distance); //krakensbane.setOffset(ps); FloatingOrigin.SetOutOfFrameOffset(ps); //AngularMomentum Block if (AMConservationMode == true) { ApplyAngularMomentum(); } } if (AMConservationMode == true && eModule.currentThrottle == 0) { SetAMStartStateVars(); } double speedcdisp = (distance) / (LIGHTSPEED * TimeWarp.fixedDeltaTime); status = String.Format("{0:g3}c [Max {1:f3}c] T@{2:f3}c", speedcdisp, maxspeeddisp, ts); } } catch (Exception ex) { print(String.Format("[WARP] Error in OnFixedUpdate - {0}", ex.Message)); } }
private void SetupPropellants(bool moveNext) { try { Current_propellant = fuel_mode < _propellants.Count ? _propellants[fuel_mode] : _propellants.FirstOrDefault(); if ((Current_propellant.SupportedEngines & type) != type) { _rep++; togglePropellant(moveNext); return; } Propellant new_propellant = Current_propellant.Propellant; List <Propellant> list_of_propellants = new List <Propellant>(); list_of_propellants.Add(new_propellant); // if all propellant exist if (!list_of_propellants.Exists(prop => PartResourceLibrary.Instance.GetDefinition(prop.name) == null)) { //Get the Ignition state, i.e. is the engine shutdown or activated var engineState = _attached_engine.getIgnitionState; _attached_engine.Shutdown(); ConfigNode newPropNode = new ConfigNode(); foreach (var prop in list_of_propellants) { ConfigNode propellantConfigNode = newPropNode.AddNode("PROPELLANT"); propellantConfigNode.AddValue("name", prop.name); propellantConfigNode.AddValue("ratio", prop.ratio); propellantConfigNode.AddValue("DrawGauge", "true"); } _attached_engine.Load(newPropNode); if (engineState == true) { _attached_engine.Activate(); } } else if (_rep < _propellants.Count) { _rep++; togglePropellant(moveNext); return; } if (HighLogic.LoadedSceneIsFlight) { // you can have any fuel you want in the editor but not in flight var allVesselResourcesNames = part.vessel.parts.SelectMany(m => m.Resources).Select(m => m.resourceName).Distinct(); if (!list_of_propellants.All(prop => allVesselResourcesNames.Contains(prop.name.Replace("LqdWater", "Water"))) && _rep < _propellants.Count) { _rep++; togglePropellant(moveNext); return; } } _rep = 0; } catch (Exception e) { UnityEngine.Debug.LogError("[KSPI] - SetupPropellants ElectricEngineControllerFX " + e.Message); } }
/* * private void OnEditorAttach() * { * Debug.Log(string.Format("{0} LES OnEditorAttach", _myModTag)); * part.transform.Rotate(0, -90, 0); * } */ public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight || vessel.HoldPhysics) { return; } if (escapeEngine != null && escapeEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - escapeEngineStartTime >= escapeEngineRunTime) { escapeEngine.Shutdown(); } // in real life, the LES had a huge chunk of depleted uranium ballast in its nosecone // in the game, when we model the LES using a single part the center of mass shifts // too far aft as solid fuel is burned, compared to real life. This makes it // difficult to maintain stable flight // while the escape engine is running, adjust the center of mass offset // until 1.2 hits, we also have to adjust the center of pressure offset since CoP // is currently incorrectly tied to the final center of mass, rather than the part origin var comFactor = (_maxFuel - part.Resources["SolidFuel"].amount) / comMult; var copFactor = (_maxFuel - part.Resources["SolidFuel"].amount) / copMult; var newComY = _origComOffset.y + (float)comFactor; var newCopY = _origCopOffset.y + (float)copFactor; part.CoMOffset.Set(_origComOffset.x, newComY, _origComOffset.z); //part.CoPOffset.Set(_origCopOffset.x, -newCopY, _origCopOffset.z); //Debug.Log(string.Format("CoMOffset updated to {0}", newY.ToString())); } if (pitchEngine != null && pitchEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - pitchEngineStartTime >= pitchEngineRunTime) { pitchEngine.Shutdown(); } } if (jettisonEngine != null && jettisonEngine.EngineIgnited) { if (Planetarium.GetUniversalTime() - jettisonEngineStartTime >= jettisonEngineRunTime) { jettisonEngine.Shutdown(); } } if (_aborted && !_deployed && (Planetarium.GetUniversalTime() >= _canardDeployTime)) { // pop the canards DeployCanards(); } if (_aborted && CheckCanAutoJettison()) { DoJettison(); } }
protected override void FailPart() { engine = part.FindModuleImplementing <ModuleEngines>(); gimbal = part.FindModuleImplementing <ModuleGimbal>(); if (engine != null) { //In the event of a fuel line leak, the chance of explosion will be reset if the engine is shut down. if (engine.currentThrottle == 0) { fuelLineCounter = 5; return; } } if (OhScrap.highlight) { OhScrap.SetFailedHighlight(); } //Randomly pick which failure we will give the player if (failureType == "none") { int i = Randomiser.instance.RandomInteger(1, 5); switch (i) { case 1: failureType = "Fuel Flow Failure"; Debug.Log("[OhScrap]: attempted to perform Fuel Flow Failure on " + SYP.ID); break; case 2: failureType = "Fuel Line Leak"; Debug.Log("[OhScrap]: attempted to perform Fuel Line Leak on " + SYP.ID); InvokeRepeating("LeakFuel", 2.0f, 2.0f); break; case 3: failureType = "Underthrust"; originalThrust = engine.thrustPercentage; Debug.Log("[OhScrap]: attempted to perform Underthrust on " + SYP.ID); break; case 4: if (gimbal == null) { return; } failureType = "Gimbal Failure"; Debug.Log("[OhScrap]: attempted to lock gimbal on" + SYP.ID); break; default: failureType = "none"; Debug.Log("[OhScrap]: " + SYP.ID + " decided not to fail after all"); break; } if (vessel.vesselType != VesselType.Debris) { ScreenMessages.PostScreenMessage(failureType + " detected on " + part.partInfo.title); } postMessage = true; return; } switch (failureType) { //Engine shutdown case "Fuel Flow Failure": engine.Shutdown(); break; //Fuel line leaks will explode the engine after anywhere between 5 and 50 seconds. case "Fuel Line Leak": if (timeBetweenFailureEvents > Planetarium.GetUniversalTime()) { break; } if (fuelLineCounter < 0) { part.explode(); } else { fuelLineCounter--; } timeBetweenFailureEvents = Planetarium.GetUniversalTime() + Randomiser.instance.RandomInteger(1, 10); break; //Engine will constantly lose thrust case "Underthrust": if (timeBetweenFailureEvents <= Planetarium.GetUniversalTime()) { engine.thrustPercentage = engine.thrustPercentage * 0.9f; timeBetweenFailureEvents = Planetarium.GetUniversalTime() + Randomiser.instance.RandomInteger(10, 30); staticThrust = engine.thrustPercentage; } engine.thrustPercentage = staticThrust; break; //lock gimbal case "Gimbal Failure": gimbal.gimbalLock = true; break; default: return; } }
public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight) { return; } if (shutdownUnder == true) //shut down a submerged engine { if (this.part.WaterContact && MPFunctions.findAltitude(this.part.transform) <= -1) { for (int i = this.part.Modules.Count - 1; i >= 0; --i) { PartModule M = this.part.Modules[i]; if (M.isActiveAndEnabled) { if (M is ModuleEnginesFX) { ModuleEnginesFX E = M as ModuleEnginesFX; if (!E.flameout) { E.Flameout("Flooded"); E.Shutdown(); } } if (M is ModuleEngines) { ModuleEngines F = M as ModuleEngines; if (!F.flameout) { F.Flameout("Flooded"); F.Shutdown(); } } } } } } else { if (!this.part.WaterContact) { for (int i = this.part.Modules.Count - 1; i >= 0; --i) { PartModule M = this.part.Modules[i]; { if (M is ModuleEnginesFX) { ModuleEnginesFX E = M as ModuleEnginesFX; if (!E.flameout) { E.Flameout("Engine out of the water"); E.Shutdown(); } } if (M is ModuleEngines) { ModuleEngines F = M as ModuleEngines; if (!F.flameout) { F.Flameout("Engine out of the water"); F.Shutdown(); } } } } } } }
private void ShutdownEngine() { //Shutdown the engine --> Removes the gauges, and make sense to do before changing propellant currentModuleEngine.Shutdown(); }
public override void StopEngine() { currentEngine.Shutdown(); }
protected override void FailPart() { if (part.Resources.Contains("SolidFuel")) { return; } engine = part.FindModuleImplementing <ModuleEngines>(); if (engine == null) { engineFX = part.FindModuleImplementing <ModuleEnginesFX>(); } gimbal = part.FindModuleImplementing <ModuleGimbal>(); if (engine != null) { if (engine.currentThrottle == 0) { fuelLineCounter = 10; return; } } else { if (engine.currentThrottle == 0) { fuelLineCounter = 10; return; } } if (UPFM.highlight) { UPFM.SetFailedHighlight(); } if (failureType == "none") { int i = Randomiser.instance.RandomInteger(1, 5); switch (i) { case 1: failureType = "Fuel Flow Failure"; Debug.Log("[UPFM]: attempted to perform Fuel Flow Failure on " + SYP.ID); break; case 2: failureType = "Fuel Line Leak"; Debug.Log("[UPFM]: attempted to perform Fuel Line Leak on " + SYP.ID); InvokeRepeating("LeakFuel", 2.0f, 2.0f); break; case 3: failureType = "Underthrust"; Debug.Log("[UPFM]: attempted to perform Underthrust on " + SYP.ID); break; case 4: if (gimbal == null) { return; } failureType = "Gimbal Failure"; Debug.Log("[UPFM]: attempted to lock gimbal on" + SYP.ID); break; default: failureType = "none"; Debug.Log("[UPFM]: " + SYP.ID + " decided not to fail after all"); break; } ScreenMessages.PostScreenMessage(failureType + " detected on " + part.name); postMessage = true; return; } switch (failureType) { case "Fuel Flow Failure": engine.Shutdown(); break; case "Fuel Line Leak": if (timeBetweenFailureEvents > Planetarium.GetUniversalTime()) { break; } if (fuelLineCounter < 0) { part.explode(); } else { fuelLineCounter--; } timeBetweenFailureEvents = Planetarium.GetUniversalTime() + 10; break; case "Underthrust": if (timeBetweenFailureEvents <= Planetarium.GetUniversalTime()) { if (engine != null) { engine.thrustPercentage = engine.thrustPercentage * 0.9f; } else { engineFX.thrustPercentage = engine.thrustPercentage * 0.9f; } timeBetweenFailureEvents = Planetarium.GetUniversalTime() + Randomiser.instance.RandomInteger(10, 30); if (engine != null) { staticThrust = engine.thrustPercentage; } else { staticThrust = engineFX.thrustPercentage; } } if (engine != null) { engine.thrustPercentage = staticThrust; } else { engineFX.thrustPercentage = staticThrust; } break; case "Gimbal Failure": gimbal.gimbalLock = true; break; default: return; } }
public static void DeactivateModule(this ModuleEngines module) { module.Shutdown(); module.Events["Activate"].active = module.Events["Activate"].guiActive = false; module.isEnabled = false; }