private void initialize() { if (initialized) { return; } if (defaultOrientations != null) { return; } //already initialized? should not have gimbalModule = part.GetComponent <ModuleGimbal>(); if (gimbalModule == null) //no module to update, may be due to ordering in part config { return; } if (gimbalModule.gimbalTransforms == null || gimbalModule.gimbalTransforms.Count <= 0)//gimbal not loaded { return; } else if (gimbalModule.initRots == null || gimbalModule.initRots.Count <= 0)//gimbal invalid? { return; } //gimbal is present, and appears to be valid, set to initialized and get default orientations array initialized = true; defaultOrientations = gimbalModule.initRots.ToArray(); updateGimbalOffset(); }
public override void OnStart(StartState state) { // parent OnStart base.OnStart(state); module = Utils.getModuleByType<ModuleGimbal>(base.part); }
// Runs on PartModule startup. public override void OnStart(StartState state) { // Startup the PartModule stuff first. base.OnStart(state); // Set our state trackers to the opposite of our states, to force first-run updates. // this.startLockedState = !this.startLocked; // Fetch the gimbal module from the part. this.gimbalModule = base.part.getFirstModuleOfType <ModuleGimbal>(); if (this.gimbalModule == null) { return; } //PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.Modules /*.OfType<ModuleGimbal>() * .FirstOrDefault() * .gimbalRange*/ #if true ModuleGimbal gimbalPrefab; if (PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.tryGetFirstModuleOfType(out gimbalPrefab)) {
public override void OnStart(PartModule.StartState state) { base.OnStart(state); List <ModuleGimbal> gimbals = base.part.Modules.OfType <ModuleGimbal>().ToList(); if (this.gimbalTransformName != "RANDOM") { for (int i = 0; i < gimbals.Count; i++) { ModuleGimbal gimbal = gimbals[i]; if (gimbal.gimbalTransformName == this.gimbalTransformName && !gimbal.gimbalLock && gimbal.gimbalRange > 0f) { this.module = gimbal; return; } } gimbalTransformName = "RANDOM"; } if (this.gimbalTransformName == "RANDOM") { List <ModuleGimbal> valid = new List <ModuleGimbal>(); for (int i = 0; i < gimbals.Count; i++) { ModuleGimbal gimbal = gimbals[i]; if (!gimbal.gimbalLock && gimbal.gimbalRange > 0f) { valid.Add(gimbal); } } int roll = UnityEngine.Random.Range(0, valid.Count); module = valid[roll]; gimbalTransformName = module.gimbalTransformName; } }
} // GetModule public void FixedUpdate() { if (HighLogic.LoadedScene != GameScenes.FLIGHT) { return; } if (null == GimbalModule) { GimbalModule = (ModuleGimbal)GetModule("ModuleGimbal"); return; } if (HighLogic.LoadedScene == GameScenes.FLIGHT && part.State == PartStates.IDLE) { GimbalModule.OnFixedUpdate(); } if (plusEnabled == true) { if (gimbalRateIsActive == true) { GimbalModule.useGimbalResponseSpeed = true; GimbalModule.gimbalResponseSpeed = gimbalResponseSpeed; } else { GimbalModule.useGimbalResponseSpeed = false; } } }
public override void OnStart(PartModule.StartState state) { base.OnStart(state); List<ModuleGimbal> gimbals = base.part.Modules.OfType<ModuleGimbal>().ToList(); if (this.gimbalTransformName != "RANDOM") { for (int i = 0; i < gimbals.Count; i++) { ModuleGimbal gimbal = gimbals[i]; if (gimbal.gimbalTransformName == this.gimbalTransformName && !gimbal.gimbalLock && gimbal.gimbalRange > 0f) { this.module = gimbal; return; } } gimbalTransformName = "RANDOM"; } if (this.gimbalTransformName == "RANDOM") { List<ModuleGimbal> valid = new List<ModuleGimbal>(); for (int i = 0; i < gimbals.Count; i++) { ModuleGimbal gimbal = gimbals[i]; if (!gimbal.gimbalLock && gimbal.gimbalRange > 0f) { valid.Add(gimbal); } } int roll = UnityEngine.Random.Range(0, valid.Count); module = valid[roll]; gimbalTransformName = module.gimbalTransformName; } }
// Runs on PartModule startup. public override void OnStart(StartState state) { // Startup the PartModule stuff first. base.OnStart(state); // Set our state trackers to the opposite of our states, to force first-run updates. // this.startLockedState = !this.startLocked; // Fetch the gimbal module from the part. this.gimbalModule = base.part.getFirstModuleOfType <ModuleGimbal>(); if (this.gimbalModule == null) { return; } //PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.Modules /*.OfType<ModuleGimbal>() * .FirstOrDefault() * .gimbalRange*/ ModuleGimbal gimbalPrefab; if (PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.tryGetFirstModuleOfType(out gimbalPrefab)) { // Initialize the gimbal range tweakable and value. TweakableTools.InitializeTweakable <ModuleTweakableGimbal>( this.Fields["gimbalRange"].uiControlCurrent(), ref this.gimbalRange, ref this.gimbalModule.gimbalRange, gimbalPrefab.gimbalRange, this.lowerMult, this.upperMult ); } // If we're in flight mode... if (HighLogic.LoadedSceneIsFlight) { // ...and if our control state and gimbal range don't match... if ( (this.reverseGimbalControl && this.gimbalRange >= 0) || (!this.reverseGimbalControl && this.gimbalRange < 0) ) { // ...toggle the reverse state. this.ToggleGimbalFlip(); // ...and seed our last state. this.reverseControlState = this.reverseGimbalControl; } } if (this.disableStockLimiter) { this.gimbalModule.Fields["gimbalLimiter"].guiActive = false; this.gimbalModule.Fields["gimbalLimiter"].guiActiveEditor = false; } }
internal Thruster(Part thrusterPart, ModuleEngines thrusterEngine, ModuleGimbal thrusterGimbal, int thrusterTransformIndex) { part = thrusterPart; engine = thrusterEngine; gimbal = thrusterGimbal; transformIndex = thrusterTransformIndex; }
public void FixedUpdate() { if (HighLogic.LoadedScene != GameScenes.FLIGHT) { return; } if (null == GimbalModule) { GimbalModule = (ModuleGimbal)GetModule("ModuleGimbal"); return; } if (HighLogic.LoadedScene == GameScenes.FLIGHT && part.State == PartStates.IDLE) { GimbalModule.OnFixedUpdate(); } if (plusEnabled == true) { if (gimbalRateIsActive == true) { GimbalModule.useGimbalResponseSpeed = true; GimbalModule.gimbalResponseSpeed = gimbalResponseSpeed; } else { GimbalModule.useGimbalResponseSpeed = false; } } }
private void SetGimbalInfo() { moduleGimbal = selectedPart.GetModule <ModuleGimbal>(); if (moduleGimbal != null) { infoItems.Add(PartInfoItem.Create("Thrust Vectoring", moduleGimbal.gimbalRange.ToString("F2"))); } }
protected override void DI_Start(StartState state) { if (HighLogic.LoadedSceneIsFlight) { this.gimbalModule = this.part.Modules.OfType <ModuleGimbal>().First(); this.engineManager = new EngineManager(this.part); } }
Engine(ModuleEngines engine) { part = new Part(engine.part); engines = new List <ModuleEngines> (); engines.Add(engine); multiModeEngine = null; gimbal = part.InternalPart.Module <ModuleGimbal> (); }
// Runs on PartModule startup. public override void OnStart(StartState state) { // Startup the PartModule stuff first. base.OnStart(state); // Set our state trackers to the opposite of our states, to force first-run updates. // this.startLockedState = !this.startLocked; // Fetch the gimbal module from the part. this.gimbalModule = base.part.getFirstModuleOfType<ModuleGimbal>(); if (this.gimbalModule == null) { return; } //PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.Modules /*.OfType<ModuleGimbal>() .FirstOrDefault() .gimbalRange*/ ModuleGimbal gimbalPrefab; if (PartLoader.getPartInfoByName(base.part.partInfo.name).partPrefab.tryGetFirstModuleOfType(out gimbalPrefab)) { // Initialize the gimbal range tweakable and value. TweakableTools.InitializeTweakable<ModuleTweakableGimbal>( this.Fields["gimbalRange"].uiControlCurrent(), ref this.gimbalRange, ref this.gimbalModule.gimbalRange, gimbalPrefab.gimbalRange, this.lowerMult, this.upperMult ); } // If we're in flight mode... if (HighLogic.LoadedSceneIsFlight) { // ...and if our control state and gimbal range don't match... if ( (this.reverseGimbalControl && this.gimbalRange >= 0) || (!this.reverseGimbalControl && this.gimbalRange < 0) ) { // ...toggle the reverse state. this.ToggleGimbalFlip(); // ...and seed our last state. this.reverseControlState = this.reverseGimbalControl; } } if (this.disableStockLimiter) { this.gimbalModule.Fields["gimbalLimiter"].guiActive = false; this.gimbalModule.Fields["gimbalLimiter"].guiActiveEditor = false; } }
internal Engine(Part part) { this.part = part; engines = part.InternalPart.Modules.OfType <ModuleEngines> ().ToList(); multiModeEngine = part.InternalPart.Module <MultiModeEngine> (); gimbal = part.InternalPart.Module <ModuleGimbal> (); if (engines.Count == 0) { throw new ArgumentException("Part is not an engine"); } }
public override void Initialize(ModuleWaterfallFX host) { base.Initialize(host); gimbalController = host.GetComponents <ModuleGimbal>().ToList().First(); if (gimbalController == null) { Utils.LogError("[GimbalController] Could not find gimbal controller on Initialize"); } }
internal Engine(Part part) { this.part = part; engine = part.InternalPart.Module <ModuleEngines> (); engineFx = part.InternalPart.Module <ModuleEnginesFX> (); gimbal = part.InternalPart.Module <ModuleGimbal> (); if (engine == null && engineFx == null) { throw new ArgumentException("Part does not have a ModuleEngines or ModuleEnginexFX PartModule"); } }
Engine(ModuleEngines engine) { Part = new Part(engine.part); engines = new List <ModuleEngines> (); engines.Add(engine); gimbal = Part.InternalPart.Module <ModuleGimbal> (); if (engine == null) { throw new ArgumentException("Part does not have a ModuleEngines PartModule"); } }
public void BindGimbal() { m_gimbal = null; if (part.Modules.Contains("ModuleGimbal")) { m_gimbal = (part.Modules["ModuleGimbal"] as ModuleGimbal); m_useGimbalResponseSpeed = m_gimbal.useGimbalResponseSpeed; m_gimbal.useGimbalResponseSpeed = true; m_gimbalResponseSpeed = m_gimbal.gimbalResponseSpeed; m_gimbal.gimbalResponseSpeed = 0.0f; } }
public override void OnStart(StartState state) { try { base.OnStart(state); gimbalModule = part.FindModuleImplementing <ModuleGimbal>(); engineModule = part.FindModuleImplementing <ModuleEngines>(); engineFlow = engineModule.fuelFlowGui; } catch (Exception ex) { Debug.LogError("PROBLEM.\n" + ex.Message + "\n" + ex.StackTrace); } }
public void AddNewEngine(ModuleEngines e) { if ((!e.EngineIgnited) || (!e.isEnabled)) { return; } // Compute the resource requirement at full thrust. // mdot = maxthrust / (Isp * g0) in tonnes per second // udot = mdot / mixdensity in units per second of propellant per ratio unit // udot * ratio_i : units per second of propellant i // Choose the worse Isp between now and after one timestep. // TODO: actually, pressure should be for the engine part, not for the spacecraft. // The pressure can easily vary by 1% from top to bottom of a spacecraft. // We'd need to compute the position of the part, which seems like a pain. float Isp0 = e.atmosphereCurve.Evaluate(atmP0); float Isp1 = e.atmosphereCurve.Evaluate(atmP1); double Isp = Math.Min(Isp0, Isp1); double udot = e.maxThrust / (Isp * 9.81 * e.mixtureDensity); foreach (var propellant in e.propellants) { double maxreq = udot * propellant.ratio; addResource(propellant.id, propellant.currentRequirement, maxreq); } if (!e.getFlameoutState) { double usableFraction = 1; // Vector3d.Dot((p.transform.rotation * e.thrustTransform.forward).normalized, forward); // TODO: Fix usableFraction thrustAvailable += e.maxThrust * usableFraction; if (e.throttleLocked) { thrustMinimum += e.maxThrust * usableFraction; } else { thrustMinimum += e.minThrust * usableFraction; } Part p = e.part; ModuleGimbal gimbal = p.Modules.OfType <ModuleGimbal>().FirstOrDefault(); if (gimbal != null && !gimbal.gimbalLock) { double gimbalRange = gimbal.gimbalRange; torqueThrustPYAvailable += Math.Sin(Math.Abs(gimbalRange) * Math.PI / 180) * e.maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; // TODO: close enough? } } }
public override void OnStart(StartState state) { Debug.Log(moduleName + ".Start(): v01.01"); //base.OnStart(state); GimbalModule = (ModuleGimbal)GetModule("ModuleGimbal"); if (null == GimbalModule) { Debug.LogWarning(moduleName + ".Start(): Did not find Gimbal Module."); return; } SetupStockPlus(); }
public override void OnStart(StartState state) { Debug.Log(moduleName + ".Start(): v01.01"); //base.OnStart(state); GimbalModule = (ModuleGimbal)GetModule("ModuleGimbal"); if (null == GimbalModule) { Debug.LogWarning(moduleName + ".Start(): Did not find Gimbal Module."); return; } SetupStockPlus(); }
public override void OnStart(PartModule.StartState state) { base.OnStart(state); Part p = base.part.partInfo.partPrefab; List <ModuleGimbal> gimbals = p.Modules.OfType <ModuleGimbal>().ToList(); for (int i = 0; i < gimbals.Count; i++) { ModuleGimbal g = gimbals[i]; if (g.gimbalTransformName == base.gimbalTransformName) { this.baseSpeed = g.gimbalResponseSpeed; break; } } }
public EngineWrapper(ModuleEngines engine) { //init thrustController.setMaster(ThrustPI); zeroIsp = engine.atmosphereCurve.Evaluate(0f); name = Utils.ParseCamelCase(engine.part.Title()); if (engine.engineID.Length > 0 && engine.engineID != "Engine") { name += " (" + engine.engineID + ")"; } //generate engine ID this.engine = engine; ID = new EngineID(this); //get info info = engine.part.Modules.GetModule <TCAEngineInfo>(); //find gimbal gimbal = engine.part.Modules.GetModule <ModuleGimbal>(); }
protected override void Overrides() { Fields["displayChance"].guiName = "Chance of Engine Failure"; Fields["safetyRating"].guiName = "Engine Safety Rating"; engine = part.FindModuleImplementing <ModuleEngines>(); engineWrapper = new EngineModuleWrapper(); engineWrapper.InitWithEngine(part, engine.engineID); gimbal = part.FindModuleImplementing <ModuleGimbal>(); //If the ISP at sea level suggests this is a space engine, change the lifetime and failure rates accordingly float staticPressure = (float)(FlightGlobals.GetHomeBody().GetPressure(0) * PhysicsGlobals.KpaToAtmospheres); if (engine.atmosphereCurve.Evaluate(staticPressure) <= 100.0f) { expectedLifetime = spaceEngineExpectedLifetime; baseChanceOfFailure = spaceEngineBaseChanceOfFailure; } }
internal void Start() { gimbalModule = part.FindModuleImplementing <ModuleGimbal>(); engineModuleList = part.FindModulesImplementing <ModuleEngines>().ToList(); engineFxModuleList = part.FindModulesImplementing <ModuleEnginesFX>().ToList(); if (toggles == null) { //if necessary, initialize static list toggles = new List <ModuleEngineGimbal>(); } toggles.Add(this); removeNullToggles(); // Clean up elements from previous iterations of the list setupCalled = true; activeFlag = !gimbalModule.gimbalLock; }
private void updateUsage(float rate) { if (module == null) { module = Utils.getModuleByType<ModuleGimbal>(base.part); return; } // usage due to time float timeUsage = usageUtils.getPartUsageInTime(rate); // usage modifier float usageMod = 1.0f; // modify usage when moving float angle = Math.Abs(module.gimbalAnglePitch) + Math.Abs(module.gimbalAngleRoll) + Math.Abs(module.gimbalAngleYaw); angle = (angle / 3) / module.gimbalRange; usageMod += 1.0f * angle; conditionGimbal = timeUsage * usageMod * usageUtils.GLOBAL_MOD; }
public EngineWrapper(ModuleEngines engine) { //generate engine ID this.engine = engine; name = Utils.ParseCamelCase(engine.part.Title()); if (engine.engineID.Length > 0 && engine.engineID != "Engine") { name += " (" + engine.engineID + ")"; } ID = new EngineID(this); //init thrustController.setMaster(ThrustPI); zeroIsp = GetIsp(0, 0, 0); //get info info = engine.part.Modules.GetModule <TCAEngineInfo>(); //find gimbal gimbal = engine.part.Modules.GetModule <ModuleGimbal>(); gimbals = new List <GimbalInfo>(engine.thrustTransforms.Count); if (gimbal != null) { for (int i = 0, eCount = engine.thrustTransforms.Count; i < eCount; i++) { var eT = engine.thrustTransforms[i]; for (int j = 0, gCount = gimbal.gimbalTransforms.Count; j < gCount; j++) { var gT = gimbal.gimbalTransforms[j]; if (Part.FindTransformInChildrenExplicit(gT, eT)) { gimbals.Add(new GimbalInfo(eT, gT, gimbal.initRots[j])); break; } } if (gimbals.Count == i) { gimbals.Add(null); } } } }
private void InitModulesFromBell() { // Set the bits and pieces selectedBell.model.gameObject.SetActive(true); if (selectedBell.atmosphereCurve != null) { Engine.atmosphereCurve = selectedBell.atmosphereCurve; } ModuleGimbal md = GetComponent <ModuleGimbal>(); if (md != null) { md.gimbalRange = selectedBell.gimbalRange; md.gimbalTransformName = selectedBell.model.transform.name; md.gimbalRangeXN = md.gimbalRangeXP = md.gimbalRangeYN = md.gimbalRangeYP = selectedBell.gimbalRange; } if (ModularEnginesChangeEngineType != null && selectedBell.realFuelsEngineType != null) { ModularEnginesChangeEngineType(selectedBell.realFuelsEngineType); } srbISP = string.Format("{0:F0}s ({1:F0}s Vac)", Engine.atmosphereCurve.Evaluate(1), Engine.atmosphereCurve.Evaluate(0)); }
public void Start() { gimbalModule = part.Modules.OfType <ModuleGimbal>().FirstOrDefault(); engineModules = part.Modules.OfType <ModuleEngines>().ToList(); engineModule = engineModules.FirstOrDefault(); if (deflectionAtThrust == null) { deflectionAtThrust = new List <List <float> >(); if (defaults == null) { defaults = new ConfigNode(EditorWindowGimbal.nodeName); } LoadConfig(defaults, true); } if (!loaded) { deflection = gimbalModule.gimbalRange; loaded = true; } }
public void BindGimbal() { m_gimbal = null; if (part.Modules.Contains("ModuleGimbal")) { m_gimbal = (part.Modules["ModuleGimbal"] as ModuleGimbal); m_useGimbalResponseSpeed = m_gimbal.useGimbalResponseSpeed; m_gimbal.useGimbalResponseSpeed = true; m_gimbalResponseSpeed = m_gimbal.gimbalResponseSpeed; m_gimbal.gimbalResponseSpeed = 0.0f; } }
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; } }
private void AnalyzeEngines() { torqueGimbal.Reset(); double thrustOverVe = 0.0; foreach (var pair in engines) { Part p = pair.Key; List <ModuleGimbal> glist = p.Modules.GetModules <ModuleGimbal>(); for (int m = 0; m < glist.Count; m++) { Vector3 pos; Vector3 neg; ModuleGimbal g = glist[m]; g.GetPotentialTorque(out pos, out neg); torqueRcs.Add(pos); torqueRcs.Add(-neg); } List <ModuleEngines> elist = p.Modules.GetModules <ModuleEngines>(); for (int m = 0; m < elist.Count; m++) { ModuleEngines e = elist[m]; if ((!e.EngineIgnited) || (!e.isEnabled) || (!e.isOperational)) { continue; } float thrustLimiter = e.thrustPercentage / 100f; double Isp0 = e.atmosphereCurve.Evaluate((float)atmPressure); double Isp1 = e.atmosphereCurve.Evaluate((float)atmPressure1); double Isp = Math.Min(Isp0, Isp1); double Ve = Isp * e.g; double maxThrust = e.maxFuelFlow * e.flowMultiplier * Ve; double minThrust = e.minFuelFlow * e.flowMultiplier * Ve; /* handle RealFuels engines */ if (e.finalThrust == 0.0f && minThrust > 0.0f) { minThrust = maxThrust = 0.0; } double eMaxThrust = minThrust + (maxThrust - minThrust) * thrustLimiter; double eMinThrust = e.throttleLocked ? eMaxThrust : minThrust; double eCurrentThrust = e.finalThrust; thrustMaximum += eMaxThrust; thrustMinimum += eMinThrust; thrustCurrent += eCurrentThrust; thrustOverVe += eMaxThrust / Ve; /* FIXME: Cosine losses */ } } totalVe = thrustMaximum / thrustOverVe; }
public EngineWrapper(ModuleEngines engine) { //init thrustController.setMaster(ThrustPI); zeroIsp = engine.atmosphereCurve.Evaluate(0f); name = Utils.ParseCamelCase(engine.part.Title()); if(engine.engineID.Length > 0 && engine.engineID != "Engine") name += " (" + engine.engineID + ")"; //generate engine ID this.engine = engine; ID = new EngineID(this); //get info info = engine.part.Modules.GetModule<TCAEngineInfo>(); //find gimbal gimbal = engine.part.Modules.GetModule<ModuleGimbal>(); }
protected override void DI_Start(StartState state) { if (HighLogic.LoadedSceneIsFlight) { this.gimbalModule = this.part.Modules.OfType<ModuleGimbal>().Single(); this.engineManager = new EngineManager(this.part); } }
public GimbalValue(ModuleGimbal gimbal, SharedObjects sharedObj):base(gimbal.part, sharedObj) { this.gimbal = gimbal; InitializeGimbalSuffixes(); }
public GimbalFields(ModuleGimbal gimbal, SharedObjects sharedObj) : base(gimbal, sharedObj) { this.gimbal = gimbal; InitializeGimbalSuffixes(); }
// Support for the new ModuleEnginesFX - lack of common interface between the 2 engins type is not fun // I can't even just copy ModuleEngines to a ModuleEnginesFX and use the same function since some field are readonly public void AddNewEngine(ModuleEnginesFX e) { if ((!e.EngineIgnited) || (!e.isEnabled)) { return; } // Compute the resource requirement at full thrust. // mdot = maxthrust / (Isp * g0) in tonnes per second // udot = mdot / mixdensity in units per second of propellant per ratio unit // udot * ratio_i : units per second of propellant i // Choose the worse Isp between now and after one timestep. // TODO: actually, pressure should be for the engine part, not for the spacecraft. // The pressure can easily vary by 1% from top to bottom of a spacecraft. // We'd need to compute the position of the part, which seems like a pain. float Isp0 = e.atmosphereCurve.Evaluate(atmP0); float Isp1 = e.atmosphereCurve.Evaluate(atmP1); double Isp = Math.Min(Isp0, Isp1); double udot = e.maxThrust / (Isp * e.g * e.mixtureDensity); // Tavert Issue #163 foreach (var propellant in e.propellants) { double maxreq = udot * propellant.ratio; addResource(propellant.id, propellant.currentRequirement, maxreq); } if (!e.getFlameoutState) { var thrustDirectionVector = new Vector3d(); foreach (var xform in e.thrustTransforms) { // The rotation makes a +z vector point in the direction that molecules are ejected // from the engine. The resulting thrust force is in the opposite direction. thrustDirectionVector += xform.rotation * new Vector3d(0, 0, -1d / (double)e.thrustTransforms.Count); } double cosineLosses = Vector3d.Dot(thrustDirectionVector, e.part.vessel.GetTransform().up); double usableFraction = e.thrustPercentage / 100f; if (e.useVelocityCurve) { usableFraction = e.velocityCurve.Evaluate((float)(e.part.vessel.orbit.GetVel() - e.part.vessel.mainBody.getRFrmVel(CoM)).magnitude); } double eMaxThrust = e.maxThrust * usableFraction * cosineLosses; double eMinThrust = e.throttleLocked ? eMaxThrust : (e.minThrust * usableFraction * cosineLosses); double eCurrentThrust = eMaxThrust * e.currentThrottle + eMinThrust * (1 - e.currentThrottle); thrustCurrent += eCurrentThrust * thrustDirectionVector; thrustMax += eMaxThrust * thrustDirectionVector; thrustMin += eMinThrust * thrustDirectionVector; Part p = e.part; ModuleGimbal gimbal = p.Modules.OfType <ModuleGimbal>().FirstOrDefault(); if (gimbal != null && !gimbal.gimbalLock) { double gimbalRange = gimbal.gimbalRange; torqueThrustPYAvailable += Math.Sin(Math.Abs(gimbalRange) * Math.PI / 180) * eCurrentThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; // TODO: close enough? } } }
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 GimbalFields(ModuleGimbal gimbal, SharedObjects sharedObj) : base(gimbal, sharedObj) { this.gimbal = gimbal; InitializeGimbalSuffixes(); }
public StockGimbal(PartModule g) { module = (ModuleGimbal)g; original_spd = GimbalSpeed; original_use_spd = UseGimbalSpeed; }
private void SetGimbalInfo() { moduleGimbal = selectedPart.GetModule<ModuleGimbal>(); if (moduleGimbal != null) { infoItems.Add(PartInfoItem.Create("Thrust Vectoring", moduleGimbal.gimbalRange.ToString("F2"))); } }
/// <summary> /// Called when the part is started. /// </summary> /// <param name="state">The start state.</param> public override void OnStart(PartModule.StartState state) { base.OnStart(state); gimbal = part.Modules.OfType<ModuleGimbal>().FirstOrDefault<ModuleGimbal>(); if (!gimbal) { Logger.DebugError("Part \"" + part.partInfo.name + "\" has no gimbal!"); } if (permanentLock) { BreakGimbal(false); } Fields["quality"].guiName = "Gimbal " + Fields["quality"].guiName; }