public void Release() { Debug.LogFormat("[ELExtendingLaunchClamp] Release"); if (!released && part.parent != null && HighLogic.LoadedSceneIsFlight) { released = true; part.decouple(); if (release_fx != null) { release_fx.Burst(); } if (anim_decouple) { anim_decouple.speed = 1; anim.Play(anim_decouple_name); } } }
public void Jettison() { if (isJettisoned) { return; } if (jettisons.Length == 0) { return; } OnMoving.Fire(0, 1); for (int i = 0; i < jettisons.Length; i++) { Rigidbody rb = physicalObject.ConvertToPhysicalObject(part, jettisons[i].gameObject).rb; rb.useGravity = true; rb.mass = jettisonedObjectMass / jettisons.Length; rb.maxAngularVelocity = PhysicsGlobals.MaxAngularVelocity; rb.angularVelocity = part.Rigidbody.angularVelocity; rb.velocity = part.Rigidbody.velocity + Vector3.Cross(part.Rigidbody.worldCenterOfMass - vessel.CurrentCoM, vessel.angularVelocity); Vector3 d = jettisonDirection; if (d == Vector3.zero) { d = Vector3.Normalize(rb.transform.position - part.transform.position); } else { d = part.transform.TransformDirection(d); } //rb.AddForce(part.transform.TransformDirection(jettisonDirection) * (jettisonForce * 0.5f), ForceMode.Force); rb.AddForceAtPosition(d * (jettisonForce * 0.5f), part.transform.position, ForceMode.Force); part.Rigidbody.AddForce(d * (-jettisonForce * 0.5f), ForceMode.Force); } jettisons = new Transform[0]; if (part.temperature < part.skinMaxTemp) { part.skinTemperature = part.temperature; } isJettisoned = true; SetJettisoned(isJettisoned); OnStop.Fire(1); EnableOtherModules(); FXGroup effect = part.findFxGroup(fxGroupName); if (effect != null) { effect.Burst(); } GameEvents.onVesselWasModified.Fire(vessel); }
protected override IEnumerable <YieldInstruction> before_vessel_launch(PackedVessel vsl) { if (fairings.Count == 0 || jettisoned) { yield break; } //save part mass for the future var partMass = part.Rigidbody.mass - vsl.mass - part.resourceMass; //store crew vsl.crew.Clear(); vsl.crew.AddRange(part.protoModuleCrew); //decouple surface attached parts and decoupleNodes var decouple = part.children .Where(p => p.srfAttachNode?.attachedPart == part) .ToList(); // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator foreach (var node in decoupleNodes) { if (node.attachedPart == null) { continue; } decouple.Add(node.attachedPart == part.parent ? part : node.attachedPart); disable_decouplers(node.id); } jettisonForces.Clear(); var jettisonPower = JettisonPower <= 1 ? Mathf.LerpUnclamped(MinJettisonPower, 1, JettisonPower) : JettisonPower; var jettisonForce = JettisonForce * jettisonPower / 2; var jettisonTorque = JettisonTorque * jettisonPower; foreach (var p in decouple) { var force_target = p; if (p == part) { force_target = part.parent; } p.decouple(); if (force_target.Rigidbody != null) { var pos = force_target.Rigidbody.worldCenterOfMass; var minForce = (float)(force_target == part.parent ? vessel.totalMass - part.MassWithChildren() : force_target.MassWithChildren()) / TimeWarp.fixedDeltaTime; var force = (pos - part.Rigidbody.worldCenterOfMass).normalized * Utils.Clamp(jettisonForce, minForce, minForce * 10); jettisonForces.Add(force_target.Rigidbody, force, pos); } yield return(null); force_target.vessel.IgnoreGForces(10); } //apply force to decoupled parts and wait for them to clear away if (jettisonForces.Count > 0) { FX?.Burst(); jettisonForces.Apply(part.Rigidbody); yield return(new WaitForSeconds(3)); } //spawn debris debris.Clear(); debris_cost = 0; debris_mass = 0; var debrisDestroyCountdown = Utils.ClampL(DestroyDebrisIn, 1); jettisonForce /= fairingsSpecificMass.Values.Max(); foreach (var f in fairings) { var specMass = fairingsSpecificMass[f]; var d = Debris.SetupOnTransform(part, f, partMass * specMass, FairingsCost, DebrisLifetime); var force = f.TransformDirection(JettisonDirection) * (jettisonForce * specMass); var pos = d.Rigidbody.worldCenterOfMass; if (!JettisonForcePos.IsZero()) { pos += f.TransformVector(JettisonForcePos); } jettisonForces.Add(d.Rigidbody, force, pos, jettisonTorque); if (DestroyDebrisIn > 0) { d.selfDestruct = debrisDestroyCountdown; } d.DetectCollisions(false); d.vessel.IgnoreGForces(10); debris_cost += FairingsCost; debris_mass += d.Rigidbody.mass; if (DestroyDebrisIn > 0) { d.selfDestructPower = explosionPower(d.Rigidbody); } debris.Add(d); } vessel.IgnoreGForces(10); jettisonForces.Apply(part.Rigidbody #if DEBUG , false #endif ); //update drag cubes part.DragCubes.SetCubeWeight("Fairing ", 0f); part.DragCubes.SetCubeWeight("Clean ", 1f); part.DragCubes.ForceUpdate(true, true, true); //this event is catched by FlightLogger StartCoroutine(CallbackUtil.DelayedCallback(10, update_debris_after_launch)); GameEvents.onStageSeparation.Fire(new EventReport(FlightEvents.STAGESEPARATION, part, vsl.name, vessel.GetDisplayName(), vessel.currentStage, $"{vsl.name} separated from {vessel.GetDisplayName()}")); FX?.Burst(); if (DestroyDebrisIn > 0 && vessel.Parts.Count == 1 && vessel.Parts.First() == part) { StartCoroutine(self_destruct(debrisDestroyCountdown)); } part.UpdateCoMOffset(Vector3.Lerp( BaseCoMOffset, part.CoMOffset, vsl.mass / (part.Rigidbody.mass - debris_mass))); jettisoned = true; update_PAW(); }