public void FixedUpdate() { if (isActive) { FXMonger.Explode(part, part.transform.position, 0f); } }
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; }
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(); }
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(); }
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); } }
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); } } } }
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(); }
protected virtual void on_vessel_loaded(Vessel vsl) { FXMonger.Explode(part, part.partTransform.position, 0); ShowDeployHint = false; }
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); } }
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()); } }
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); }
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);
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); } }