Example #1
0
 public void FixedUpdate()
 {
     if (isActive)
     {
         FXMonger.Explode(part, part.transform.position, 0f);
     }
 }
Example #2
0
        void DeploySubmunitions()
        {
            missileLauncher.sfAudioSource.PlayOneShot(GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/flare"));
            FXMonger.Explode(part, transform.position + part.rb.velocity * Time.fixedDeltaTime, 0.1f);

            deployed = true;
            if (swapCollidersOnDeploy)
            {
                foreach (var col in part.GetComponentsInChildren <Collider>())
                {
                    col.enabled = !col.enabled;
                }
            }

            missileLauncher.sfAudioSource.priority = 999;
            //missileLauncher.explosionSize = 3;

            foreach (var sub in submunitions)
            {
                sub.SetActive(true);
                sub.transform.parent = null;
                Vector3   direction = (sub.transform.position - part.transform.position).normalized;
                Rigidbody subRB     = sub.GetComponent <Rigidbody>();
                subRB.isKinematic = false;
                subRB.velocity    = part.rb.velocity +
                                    (UnityEngine.Random.Range(submunitionMaxSpeed / 10, submunitionMaxSpeed) * direction);

                Submunition subScript = sub.AddComponent <Submunition>();
                subScript.enabled          = true;
                subScript.deployed         = true;
                subScript.sourceVessel     = missileLauncher.SourceVessel;
                subScript.blastForce       = missileLauncher.blastPower;
                subScript.blastHeat        = missileLauncher.blastHeat;
                subScript.blastRadius      = missileLauncher.blastRadius;
                subScript.subExplModelPath = subExplModelPath;
                subScript.subExplSoundPath = subExplSoundPath;
                sub.AddComponent <KSPForceApplier>();
            }

            foreach (var fairing in fairings)
            {
                Vector3   direction = (fairing.transform.position - part.transform.position).normalized;
                Rigidbody fRB       = fairing.GetComponent <Rigidbody>();
                fRB.isKinematic = false;
                fRB.velocity    = part.rb.velocity + ((submunitionMaxSpeed + 2) * direction);
                fairing.AddComponent <KSPForceApplier>();
                fairing.GetComponent <KSPForceApplier>().drag = 0.2f;
                ClusterBombFairing fairingScript = fairing.AddComponent <ClusterBombFairing>();
                fairingScript.deployed     = true;
                fairingScript.sourceVessel = vessel;
            }

            part.explosionPotential  = 0;
            missileLauncher.HasFired = false;

            part.temperature = part.maxTemp + 10;
        }
 private void UnAnchor()
 {
     isAnchored     = false;
     part.mass      = oldMass;
     part.CoMOffset = oldOffset;
     //part.GetComponent<Rigidbody>().isKinematic = false;
     FXMonger.Explode(part, anchorPoint.position, 0f);
     Events["Anchor"].guiActive   = true;
     Events["UnAnchor"].guiActive = false;
 }
 private void Anchor()
 {
     isAnchored     = true;
     oldMass        = part.mass;
     oldOffset      = part.CoMOffset;
     part.mass      = anchorMass;
     part.CoMOffset = new Vector3(0, offset, 0);
     //part.GetComponent<Rigidbody>().isKinematic = true;
     FXMonger.Explode(part, anchorPoint.position, 0f);
     Events["Anchor"].guiActive   = false;
     Events["UnAnchor"].guiActive = true;
 }
Example #5
0
        private IEnumerator <YieldInstruction> self_destruct()
        {
            var endUT = Planetarium.GetUniversalTime() + selfDestruct;

            while (Planetarium.GetUniversalTime() < endUT)
            {
                yield return(null);
            }
            FXMonger.Explode(part, vessel.GetWorldPos3D(), selfDestructPower);
            yield return(null);

            part.Die();
        }
Example #6
0
        private IEnumerator <YieldInstruction> self_destruct(float countdown)
        {
            var endUT = Planetarium.GetUniversalTime() + countdown;

            while (Planetarium.GetUniversalTime() < endUT)
            {
                yield return(null);
            }
            FXMonger.Explode(part, vessel.GetWorldPos3D(), explosionPower(part.Rigidbody));
            yield return(null);

            part.Die();
        }
Example #7
0
        protected void detonatePulse()
        {
            if (fuelSupply == null)
            {
                return;
            }
            totalVesselMass = 0f;
            foreach (Part current in this.vessel.parts)
            {
                totalVesselMass += current.mass;
            }

            currentUnit = fuelSupply.getUnit(false);
            if (currentUnit != null)
            {
                float neededCharge   = currentUnit.getEnergy() / (activationRatio * efficiency);
                float rechargeAmount = -currentUnit.getEnergy() / efficiency;
                float charge         = getECInBank();
                Debug.Log(charge + ":" + neededCharge);
                if (charge < neededCharge)
                {
                    Debug.Log(charge + " " + neededCharge + " " + (charge - neededCharge));
                    return;
                }
                fuelSupply.getUnit(true);
                consumeCharge(neededCharge);
                RequestResource("ElectricCharge", rechargeAmount);
                // add velocity
                this.vessel.ChangeWorldVelocity(base.transform.up * (this.currentUnit.getImpulse() / totalVesselMass));

                base.rigidbody.AddRelativeForce(new Vector3(0f, (this.currentUnit.getImpulse() / totalVesselMass), 0f), ForceMode.Force);

                if (this.Modules.Contains("HeatTransfer"))
                {
                    this.temperature += currentUnit.getEnergy() / 50000;
                }

                // FX: make explosion sound
                this.explosionGroup.Power = 10;
                this.explosionGroup.Burst();
                base.gameObject.audio.pitch = 1f;
                base.gameObject.audio.PlayOneShot(this.explosionGroup.sfx);

                //TODO replace this with a jet of plasma
                Vector3d groundZero = new Vector3d(base.transform.FindChild("model").localPosition.x, base.transform.FindChild("model").localPosition.y, base.transform.FindChild("model").localPosition.z);
                groundZero = base.transform.FindChild("model").TransformPoint(groundZero);
                FXMonger.Explode(this, groundZero, 10);
            }
        }
Example #8
0
        private void ApplyAeroStressFailure()
        {
            bool failureOccured = false;

            if (part.Modules.Contains <ModuleProceduralFairing>())
            {
                var fairing = part.Modules.GetModule <ModuleProceduralFairing>();
                fairing.ejectionForce = 0.5f;

                fairing.DeployFairing();
                failureOccured = true;
            }

            List <Part> children = part.children;

            // ReSharper disable once ForCanBeConvertedToForeach -> decouple modifies collection
            for (int i = 0; i < children.Count; i++)
            {
                Part child = children[i];
                child.decouple(25);

                failureOccured = true;
            }

            if (part.parent)
            {
                part.decouple(25);
                failureOccured = true;
            }

            if (!failureOccured || !vessel)
            {
                return;
            }
            vessel.SendMessage("AerodynamicFailureStatus");
            string msg = Localizer.Format("FARFlightLogAeroFailure",
                                          KSPUtil.PrintTimeStamp(FlightLogger.met),
                                          part.partInfo.title);

            FlightLogger.eventLog.Add(msg);
            if (FARDebugValues.aeroFailureExplosions)
            {
                FXMonger.Explode(part, partTransform.position, (float)projectedArea.totalArea * 0.0005f);
            }
        }
        private void ApplyAeroStressFailure()
        {
            bool failureOccured = false;

            if (part.Modules.Contains("ModuleProceduralFairing"))
            {
                ModuleProceduralFairing fairing = (ModuleProceduralFairing)part.Modules["ModuleProceduralFairing"];
                fairing.ejectionForce = 0.5f;

                fairing.DeployFairing();
                failureOccured = true;
            }

            List <Part> children = part.children;

            for (int i = 0; i < children.Count; i++)
            {
                Part child = children[i];
                child.decouple(25);


                failureOccured = true;
            }
            if (part.parent)
            {
                part.decouple(25);
                failureOccured = true;
            }

            if (failureOccured)
            {
                if (vessel)
                {
                    vessel.SendMessage("AerodynamicFailureStatus");
                    string msg = String.Format("[{0:D2}:{1:D2}:{2:D2}] {3} failed due to aerodynamic stresses.", FlightLogger.met_hours, FlightLogger.met_mins, FlightLogger.met_secs, part.partInfo.title);
                    FlightLogger.eventLog.Add(msg);
                    if (FARDebugValues.aeroFailureExplosions)
                    {
                        FXMonger.Explode(part, partTransform.position, (float)projectedArea.totalArea * 0.0005f);
                    }
                }
            }
        }
Example #10
0
        IEnumerator <YieldInstruction> launch_complete_construct()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                yield break;
            }
            while (!FlightGlobals.ready)
            {
                yield return(null);
            }
            vessel_spawner.BeginLaunch();
            //hide UI
            GameEvents.onHideUI.Fire();
            yield return(null);

            //save the game
            GroundConstructionScenario.SaveGame(kit.Name + "-before_launch");
            yield return(null);

            yield return(new WaitForFixedUpdate());

            //load ship construct and launch it
            var construct = kit.LoadConstruct();

            if (construct == null)
            {
                Utils.Log("Unable to load ShipConstruct {}. "
                          + "This usually means that some parts are missing "
                          + "or some modules failed to initialize.",
                          kit.Name);
                Utils.Message("Something went wrong. Constructed ship cannot be launched.");
                GameEvents.onShowUI.Fire();
                vessel_spawner.AbortLaunch();
                yield break;
            }
            model.gameObject.SetActive(false);
            FXMonger.Explode(part, part.partTransform.position, 0);
            yield return(StartCoroutine(launch(construct)));

            GameEvents.onShowUI.Fire();
            part.Die();
        }
Example #11
0
 protected virtual void on_vessel_loaded(Vessel vsl)
 {
     FXMonger.Explode(part, part.partTransform.position, 0);
     ShowDeployHint = false;
 }
Example #12
0
        public Vector3d RunDragCalculation(Vector3d velocity, double MachNumber, double rho, double failureForceScaling)
        {
            if (isShielded)
            {
                Cl = Cd = Cm = 0;
                return(Vector3d.zero);
            }

            double v_scalar = velocity.magnitude;

            if (v_scalar > 0.1)         //Don't Bother if it's not moving or in space
            {
                CoDshift = Vector3d.zero;
                Cd       = 0;

                Vector3d velocity_normalized = velocity / v_scalar;

                Vector3d upVector = part_transform.TransformDirection(localUpVector);
                perp    = Vector3d.Cross(upVector, velocity).normalized;
                liftDir = Vector3d.Cross(velocity, perp).normalized;

                Vector3d local_velocity = part_transform.InverseTransformDirection(velocity_normalized);
                DragModel(local_velocity, MachNumber, rho);

                double   qS           = 0.5 * rho * v_scalar * v_scalar * S; //dynamic pressure, q
                Vector3d D            = velocity_normalized * (-qS * Cd);    //drag
                Vector3d L            = liftDir * (qS * Cl);
                Vector3d force        = (L + D) * 0.001;
                double   force_scalar = force.magnitude;
                currentDrag = (float)force_scalar;
                Vector3d moment = perp * (qS * Cm * 0.001);

                Rigidbody rb = part.Rigidbody;

                if (HighLogic.LoadedSceneIsFlight && (object)rb != null)
                {
                    if (rb.angularVelocity.sqrMagnitude != 0)
                    {
                        Vector3d rot = Vector3d.Exclude(velocity_normalized, rb.angularVelocity);  //This prevents aerodynamic damping a spinning object if its spin axis is aligned with the velocity axis

                        rot *= (-0.00001 * qS);


                        moment += rot;
                    }
                }


                //Must handle aero-structural failure before transforming CoD pos and adding pitching moment to forces or else parts with blunt body drag fall apart too easily
                if (Math.Abs(Vector3d.Dot(force, upVector)) > YmaxForce * failureForceScaling || Vector3d.Exclude(upVector, force).magnitude > XZmaxForce * failureForceScaling)
                {
                    if (part.parent && !vessel.packed)
                    {
                        part.SendEvent("AerodynamicFailureStatus");
                        FlightLogger.eventLog.Add("[" + FARMathUtil.FormatTime(vessel.missionTime) + "] Joint between " + part.partInfo.title + " and " + part.parent.partInfo.title + " failed due to aerodynamic stresses.");
                        part.decouple(25);
                        if (FARDebugValues.aeroFailureExplosions)
                        {
                            FXMonger.Explode(part, GetCoDWithoutMomentShift(), 5);
                        }
                    }
                }

                globalCoDShift = Vector3d.Cross(force, moment) / (force_scalar * force_scalar);

                if (double.IsNaN(force_scalar) || double.IsNaN(moment.sqrMagnitude) || double.IsNaN(globalCoDShift.sqrMagnitude))
                {
                    Debug.LogWarning("FAR Error: Aerodynamic force = " + force.magnitude + " Aerodynamic moment = " + moment.magnitude + " CoD Local = " + CoDshift.magnitude + " CoD Global = " + globalCoDShift.magnitude + " " + part.partInfo.title);
                    force = moment = CoDshift = globalCoDShift = Vector3.zero;


                    return(force);
                }
                double numericalControlFactor = (rb.mass * v_scalar * 0.67) / (force_scalar * TimeWarp.fixedDeltaTime);
                force *= Math.Min(numericalControlFactor, 1);

                //part.Rigidbody.AddTorque(moment);
                return(force);
            }
            else
            {
                return(Vector3d.zero);
            }
        }
Example #13
0
 protected override void on_vessel_launched(Vessel vsl)
 {
     base.on_vessel_launched(vsl);
     if (recipient_node != null)
     {
         var construction_node_pos =
             part.partTransform.TransformPoint(construction_node.position);
         var construction_part = recipient_node.owner;
         var docking_node      = kit.GetDockingNode(vsl, ConstructDockingNode);
         if (docking_node == null)
         {
             Utils.Message(
                 "No suitable attachment node found in \"{0}\" to dock it to the {1}",
                 vsl.GetDisplayName(),
                 construction_part.Title());
             return;
         }
         var docking_offset =
             docking_node.owner.partTransform.TransformPoint(docking_node.position)
             - construction_node_pos;
         FXMonger.Explode(part, construction_node_pos, 0);
         var docking_part = docking_node.owner;
         this.Log("Docking {} to {}", docking_part.GetID(), construction_part.GetID());
         // vessels' position and rotation
         construction_part.vessel.SetPosition(construction_part.vessel.transform.position,
                                              true);
         construction_part.vessel.SetRotation(construction_part.vessel.transform.rotation);
         docking_part.vessel.SetPosition(
             docking_part.vessel.transform.position - docking_offset,
             true);
         docking_part.vessel.SetRotation(docking_part.vessel.transform.rotation);
         construction_part.vessel.IgnoreGForces(10);
         docking_part.vessel.IgnoreGForces(10);
         if (construction_part == part.parent)
         {
             part.decouple();
         }
         else
         {
             construction_part.decouple();
         }
         recipient_node.attachedPart   = docking_part;
         recipient_node.attachedPartId = docking_part.flightID;
         docking_node.attachedPart     = construction_part;
         docking_node.attachedPartId   = construction_part.flightID;
         docking_part.Couple(construction_part);
         // manage docking ports, if any
         foreach (var port in construction_part.FindModulesImplementing <ModuleDockingNode>())
         {
             if (port.referenceNode == recipient_node)
             {
                 port.dockedPartUId = docking_part.persistentId;
                 port.fsm.StartFSM(port.st_preattached);
                 break;
             }
         }
         foreach (var port in docking_part.FindModulesImplementing <ModuleDockingNode>())
         {
             if (port.referenceNode == docking_node)
             {
                 port.dockedPartUId = construction_part.persistentId;
                 port.fsm.StartFSM(port.st_preattached);
                 break;
             }
         }
         // add fuel lookups
         construction_part.fuelLookupTargets.Add(docking_part);
         docking_part.fuelLookupTargets.Add(construction_part);
         GameEvents.onPartFuelLookupStateChange.Fire(
             new GameEvents.HostedFromToAction <bool, Part>(true,
                                                            docking_part,
                                                            construction_part));
         FlightGlobals.ForceSetActiveVessel(construction_part.vessel);
         FlightInputHandler.SetNeutralControls();
         GameEvents.onVesselWasModified.Fire(construction_part.vessel);
         recipient_node = null;
         this.Log("Docked {} to {}, new vessel {}",
                  docking_part,
                  construction_part,
                  construction_part.vessel.GetID());
     }
 }
Example #14
0
        private bool updateScaffold(float newDeploymentProgress)
        {
            if (newDeploymentProgress < 0)
            {
                if (segmentScaffold != null)
                {
                    if (!removeDockingNode())
                    {
                        return(false);
                    }
                    if (HighLogic.LoadedSceneIsFlight)
                    {
                        FXMonger.Explode(part, segmentScaffold.transform.position, 0);
                    }
                    Destroy(segmentScaffold);
                    segmentScaffold = null;
                    resetRendererCaches();
                }
            }
            else
            {
                if (segmentScaffold == null)
                {
                    this.Debug($"Creating new scaffold");
                    var attachmentPoint = getAttachmentTransform();
                    if (attachmentPoint == null)
                    {
                        return(false);
                    }
                    segmentScaffold = Instantiate(segmentScaffoldPrefab, attachmentPoint, false);
                    segmentScaffold.transform.localPosition = Vector3.zero;
                    segmentScaffold.transform.localRotation = Quaternion.identity;
                    if (!string.IsNullOrEmpty(constructionPortTransformPrefabName))
                    {
                        var dockingNode =
                            Part.FindHeirarchyTransform(segmentScaffold.transform, constructionPortTransformPrefabName);
                        if (dockingNode != null)
                        {
                            dockingNode.gameObject.name = constructionPortTransformName;
                        }
                        else
                        {
                            this.Error($"Unable to find {constructionPortTransformPrefabName} transform");
                        }
                    }
                    segmentScaffold.SetActive(true);
                    resetRendererCaches();
#if DEBUG
                    this.Debug($"Scaffold instance tree: {DebugUtils.formatTransformTree(segmentScaffold.transform)}");
#endif
                }
                if (newDeploymentProgress < 1 && !removeDockingNode())
                {
                    return(false);
                }
                if (newDeploymentProgress >= 1)
                {
                    newDeploymentProgress = 1;
                }
                segmentScaffold.transform.localScale =
                    Vector3.Lerp(ScaffoldStartScale, Vector3.one, newDeploymentProgress);
                segmentScaffold.transform.hasChanged = true;
            }
            DeploymentProgress = newDeploymentProgress;
            if (DeploymentProgress >= 1)
            {
                this.Debug($"Deployment finished. Docking node: {constructionPort.GetID()}");
                setupDockingNode();
            }
            return(true);
        }
Example #15
0
        void DeploySubmunitions()
        {
            missileLauncher.sfAudioSource.PlayOneShot(GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/flare"));
            FXMonger.Explode(part, transform.position + part.rb.velocity * Time.fixedDeltaTime, 0.1f);

            deployed = true;
            if (swapCollidersOnDeploy)
            {
                IEnumerator <Collider> col = part.GetComponentsInChildren <Collider>().AsEnumerable().GetEnumerator();
                while (col.MoveNext())
                {
                    if (col.Current == null)
                    {
                        continue;
                    }
                    col.Current.enabled = !col.Current.enabled;
                }
                col.Dispose();
            }

            missileLauncher.sfAudioSource.priority = 999;

            List <GameObject> .Enumerator sub = submunitions.GetEnumerator();
            while (sub.MoveNext())
            {
                if (sub.Current == null)
                {
                    continue;
                }
                sub.Current.SetActive(true);
                sub.Current.transform.parent = null;
                Vector3   direction = (sub.Current.transform.position - part.transform.position).normalized;
                Rigidbody subRB     = sub.Current.GetComponent <Rigidbody>();
                subRB.isKinematic = false;
                subRB.velocity    = part.rb.velocity + Krakensbane.GetFrameVelocityV3f() +
                                    (UnityEngine.Random.Range(submunitionMaxSpeed / 10, submunitionMaxSpeed) * direction);

                Submunition subScript = sub.Current.AddComponent <Submunition>();
                subScript.enabled          = true;
                subScript.deployed         = true;
                subScript.blastForce       = missileLauncher.GetTntMass();
                subScript.blastHeat        = missileLauncher.blastHeat;
                subScript.blastRadius      = missileLauncher.GetBlastRadius();
                subScript.subExplModelPath = subExplModelPath;
                subScript.subExplSoundPath = subExplSoundPath;
                sub.Current.AddComponent <KSPForceApplier>();
            }

            List <GameObject> .Enumerator fairing = fairings.GetEnumerator();
            while (fairing.MoveNext())
            {
                if (fairing.Current == null)
                {
                    continue;
                }
                Vector3   direction = (fairing.Current.transform.position - part.transform.position).normalized;
                Rigidbody fRB       = fairing.Current.GetComponent <Rigidbody>();
                fRB.isKinematic = false;
                fRB.velocity    = part.rb.velocity + Krakensbane.GetFrameVelocityV3f() + ((submunitionMaxSpeed + 2) * direction);
                fairing.Current.AddComponent <KSPForceApplier>();
                fairing.Current.GetComponent <KSPForceApplier>().drag = 0.2f;
                ClusterBombFairing fairingScript = fairing.Current.AddComponent <ClusterBombFairing>();
                fairingScript.deployed = true;
            }

            fairing.Dispose();

            part.explosionPotential  = 0;
            missileLauncher.HasFired = false;

            part.Destroy();
        }
 protected virtual void on_vessel_loaded(Vessel vsl) =>
 FXMonger.Explode(part, part.partTransform.position, 0);
Example #17
0
        IEnumerable recycle(
            Part p,
            float efficiency,
            bool discard_excess_resources,
            HashSet <uint> skip_craftIDs = null
            )
        {
            // first handle children
            var skip = false;

            if (p.children.Count > 0)
            {
                for (int i = p.children.Count - 1; i >= 0; i--)
                {
                    foreach (var child_result in recycle(p.children[i],
                                                         efficiency,
                                                         discard_excess_resources,
                                                         skip_craftIDs))
                    {
                        if (child_result is SkipPart)
                        {
                            skip = true;
                        }
                        else
                        {
                            yield return(child_result);

                            if (child_result == null)
                            {
                                yield break;
                            }
                        }
                    }
                }
            }
            // decide if we have to skip this part (and thus all the parents)
            if (p.protoModuleCrew.Count > 0)
            {
                recycle_report.Add($"Skipped '{p.partInfo.title}' because the crew was inside");
                skip = true;
            }
            else
            {
                skip |= skip_craftIDs != null && skip_craftIDs.Contains(p.craftID);
            }
            if (!skip)
            {
                // if not, collect its resources if we can, else skip it anyway
                foreach (var res in p.Resources)
                {
                    if (res.amount > 0)
                    {
                        if (transfer_resource(p, res.info.id, res.amount, discard_excess_resources)
                            != TransferState.FULL)
                        {
                            skip = true;
                        }
                    }
                }
            }
            if (skip)
            {
                yield return(new SkipPart());

                yield break;
            }
            // recycle the part that is now empty
            GetRecycleInfo(p, efficiency, out var req_a, out var req_c);
            var result = recycle_part(p, discard_excess_resources, req_a, req_c);

            if (result > TransferState.ZERO)
            {
                FXMonger.Explode(p, p.transform.position, 0);
                p.Die();
            }
            // wait for some time before recycle next one, or break the recycling if something went wrong
            if (result == TransferState.NO_EC)
            {
                yield return(new SkipPart());
            }
            else if (result == TransferState.FULL)
            {
                yield return(new WaitForSeconds(GLB.RecycleRate));
            }
            else
            {
                yield return(null);
            }
        }