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);
         }
     }
 }
Example #2
0
        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);
        }
Example #3
0
        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();
        }