public bool ProcessMessage(ExplosionEventArgs message) { if (message == null) { return(false); } Vector3 offsetCorrection = Vector3.zero; if (message.TargetVesselId != Guid.Empty) { Vector3 vesselPositionInClient = new Vector3(message.TargetVesselComX, message.TargetVesselComY, message.TargetVesselComZ); Vessel vessel = FlightGlobals.VesselsLoaded.FirstOrDefault(v => v.id == message.TargetVesselId); if (vessel != null && !vessel.packed) { // calculating offset offsetCorrection = vessel.CoM - vesselPositionInClient; } } ExplosionFx.CreateVisualExplosion(new Vector3(message.PositionX, message.PositionY, message.PositionZ), message.TntMassEquivalent, message.ExplosionModelPath, message.SoundPath, new Vector3(message.DirectionX, message.DirectionY, message.DirectionZ)); return(true); }
void OnCollisionEnter(Collision col) { ContactPoint contact = col.contacts[0]; Vector3 pos = contact.point; ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, true); }
private bool ExplosiveDetonation(Part hitPart, RaycastHit hit, Ray ray, bool airDetonation = false) { /////////////////////////////////////////////////////////////////////// // High Explosive Detonation /////////////////////////////////////////////////////////////////////// if (hitPart == null || hitPart.vessel != sourceVessel) { //if bullet hits and is HE, detonate and kill bullet if (explosive) { if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Detonation Triggered | penetration: " + hasPenetrated + " penTick: " + penTicker + " airDet: " + airDetonation); } if (airDetonation) { ExplosionFx.CreateExplosion(hit.point, GetExplosivePower(), explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName); } else { ExplosionFx.CreateExplosion(hit.point - (ray.direction * 0.1f), GetExplosivePower(), explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction: currentVelocity); } KillBullet(); hasDetonated = true; return(true); } } return(false); }
void Detonate(Vector3 pos) { BDArmorySetup.numberOfParticleEmitters--; ExplosionFx.CreateExplosion(pos, BlastPhysicsUtils.CalculateExplosiveMass(blastRadius), explModelPath, explSoundPath, true); IEnumerator <KSPParticleEmitter> emitter = pEmitters.AsEnumerable().GetEnumerator(); while (emitter.MoveNext()) { if (emitter.Current == null) { continue; } if (!emitter.Current.useWorldSpace) { continue; } emitter.Current.gameObject.AddComponent <BDAParticleSelfDestruct>(); emitter.Current.transform.parent = null; } emitter.Dispose(); Destroy(gameObject); //destroy rocket on collision }
void OnCollisionEnter(Collision col) { ContactPoint contact = col.contacts[0]; Vector3 pos = contact.point; ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, ExplosionSourceType.Missile, 0, null, sourceVesselName); }
void FixedUpdate() { if (!gameObject.activeInHierarchy) { return; } //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; startPosition -= FloatingOrigin.OffsetNonKrakensbane; } if (tracerLength == 0) { // visual tracer velocity is relative to the observer linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()) * tracerDeltaFactor * 0.45f * Time.fixedDeltaTime); } else { linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()).normalized * tracerLength); } if (fadeColor) { FadeColor(); bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance); } linePositions[1] = transform.position; bulletTrail.SetPositions(linePositions); if (Time.time > timeToLiveUntil) //kill bullet when TTL ends { KillBullet(); return; } if (CheckBulletCollision(Time.fixedDeltaTime)) { return; } MoveBullet(Time.fixedDeltaTime); ////////////////////////////////////////////////// //Flak Explosion (air detonation/proximity fuse) ////////////////////////////////////////////////// if (ProximityAirDetonation((float)distanceTraveled)) { //detonate ExplosionFx.CreateExplosion(currPosition, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, currentVelocity); KillBullet(); return; } }
private void Detonate() { if (!hasDetonated && Armed) { ExplosionFx.CreateExplosion(part.transform.position, tntMass, explModelPath, explSoundPath, true, 0, part); } }
public static void ForceDeadVessel(Vessel v) { Debug.Log("[BDArmory.Misc]: GM Killed Vessel " + v.GetDisplayName()); foreach (var missileFire in VesselModuleRegistry.GetModules <MissileFire>(v)) { PartExploderSystem.AddPartToExplode(missileFire.part); ExplosionFx.CreateExplosion(missileFire.part.transform.position, 0.2f, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, missileFire.part); } }
public static void ForceDeadVessel(Vessel v) { Debug.Log("[BDArmory] GM Killed Vessel " + v.GetDisplayName()); foreach (MissileFire missileFire in v.FindPartModulesImplementing <MissileFire>()) { PartExploderSystem.AddPartToExplode(missileFire.part); ExplosionFx.CreateExplosion(missileFire.part.transform.position, 0.2f, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, missileFire.part); } }
void Detonate(Vector3 pos, Part partHit = null) { if (partHit != null) { ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, true, targetVessel: partHit.vessel); } else { ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, true); } Destroy(gameObject); }
private void Detonate() { if (!hasDetonated && Armed) { if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDExplosivePart]: " + part + " (" + (uint)(part.GetInstanceID()) + ") from " + sourcevessel?.vesselName + " detonating."); } ExplosionFx.CreateExplosion(part.transform.position, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, part, sourcevessel?.vesselName, part.FindModuleImplementing <EngageableWeapon>().GetShortName()); hasDetonated = true; part.Destroy(); } }
public void DetonateIfPossible() { if (!hasDetonated && Armed) { Vector3 direction = default(Vector3); if (Shaped) { direction = (part.transform.position + part.rb.velocity * Time.deltaTime).normalized; } ExplosionFx.CreateExplosion(part.transform.position, tntMass, explModelPath, explSoundPath, true, 0, part, direction); hasDetonated = true; } }
void Detonate(Vector3 pos, bool missed) { if (!missed) { if (tntMass > 0) { Vector3 direction = default(Vector3); if (shaped) { direction = (pos + rb.velocity * Time.deltaTime).normalized; } ExplosionFx.CreateExplosion(pos, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction); } } // needs to be Explosiontype Bullet since missile only returns Module MissileLauncher gameObject.SetActive(false); }
public void DetonateIfPossible() { if (!hasDetonated && Armed) { Vector3 direction = default(Vector3); if (Shaped) { direction = (part.transform.position + part.rb.velocity * Time.deltaTime).normalized; } ExplosionFx.CreateExplosion(part.transform.position, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, part, sourcevessel?.vesselName, part.FindModuleImplementing <EngageableWeapon>().GetShortName(), direction); hasDetonated = true; if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDExplosivePart]: " + part + " (" + (uint)(part.GetInstanceID()) + ") from " + sourcevessel?.vesselName + " detonating."); } } }
void Detonate(Vector3 pos, bool missed) { if (!missed) { if (tntMass > 0) { Vector3 direction = default(Vector3); if (shaped) { direction = (pos + rb.velocity * Time.deltaTime).normalized; } if (gravitic) { using (var hitsEnu = Physics.OverlapSphere(transform.position, blastRadius, 557057).AsEnumerable().GetEnumerator()) { while (hitsEnu.MoveNext()) { if (hitsEnu.Current == null) { continue; } Part partHit = hitsEnu.Current.GetComponentInParent <Part>(); if (partHit == null) { continue; } if (ProjectileUtils.IsIgnoredPart(partHit)) { continue; // Ignore ignored parts. } float distance = Vector3.Distance(transform.position, partHit.transform.position); if (gravitic) { if (partHit.mass > 0) { var ME = partHit.vessel.rootPart.FindModuleImplementing <ModuleMassAdjust>(); if (ME == null) { ME = (ModuleMassAdjust)partHit.vessel.rootPart.AddModule("ModuleMassAdjust"); } ME.massMod += (massMod * (1 - (distance / blastRadius))); //this way craft at edge of blast might only get disabled instead of bricked ME.duration += (BDArmorySettings.WEAPON_FX_DURATION * (1 - (distance / blastRadius))); //can bypass EMP damage cap } } } } } if (incendiary) { for (int f = 0; f < 20; f++) //throw 20 random raytraces out in a sphere and see what gets tagged { Ray LoSRay = new Ray(transform.position, VectorUtils.GaussianDirectionDeviation(transform.forward, 170)); RaycastHit hit; if (Physics.Raycast(LoSRay, out hit, blastRadius * 1.2f, 9076737)) // only add fires to parts in LoS of blast { KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); Part p = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>(); float distance = Vector3.Distance(transform.position, hit.point); if (p != null) { BulletHitFX.AttachFire(hit, p, caliber, sourceVesselName, BDArmorySettings.WEAPON_FX_DURATION * (1 - (distance / blastRadius)), 1, false, true); //else apply fire to occluding part if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory.Rocket]: Applying fire to " + p.name + " at distance " + distance + "m, for " + BDArmorySettings.WEAPON_FX_DURATION * (1 - (distance / blastRadius)) + " seconds"); } ; } } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[Rocket] incendiary raytrace: " + hit.point.x + "; " + hit.point.y + "; " + hit.point.z); } } } if (concussion || EMP || choker) { using (var hitsEnu = Physics.OverlapSphere(transform.position, 25, 557057).AsEnumerable().GetEnumerator()) { var craftHit = new HashSet <Vessel>(); while (hitsEnu.MoveNext()) { if (hitsEnu.Current == null) { continue; } if (hitsEnu.Current.gameObject == FlightGlobals.currentMainBody.gameObject) { continue; // Ignore terrain hits. } Part partHit = hitsEnu.Current.GetComponentInParent <Part>(); if (partHit == null) { continue; } if (ProjectileUtils.IsIgnoredPart(partHit)) { continue; // Ignore ignored parts. } if (craftHit.Contains(partHit.vessel)) { continue; // Don't hit the same craft multiple times. } craftHit.Add(partHit.vessel); float Distance = Vector3.Distance(partHit.transform.position, this.transform.position); if (partHit != null) { if (concussion && partHit.mass > 0) { partHit.rb.AddForceAtPosition((partHit.transform.position - this.transform.position).normalized * impulse, partHit.transform.position, ForceMode.Acceleration); } if (EMP) { var MDEC = partHit.vessel.rootPart.FindModuleImplementing <ModuleDrainEC>(); if (MDEC == null) { MDEC = (ModuleDrainEC)partHit.vessel.rootPart.AddModule("ModuleDrainEC"); } MDEC.incomingDamage += ((25 - Distance) * 5); //this way craft at edge of blast might only get disabled instead of bricked MDEC.softEMP = false; //can bypass EMP damage cap } if (choker) { var ash = partHit.vessel.rootPart.FindModuleImplementing <ModuleDrainIntakes>(); if (ash == null) { ash = (ModuleDrainIntakes)partHit.vessel.rootPart.AddModule("ModuleDrainIntakes"); } ash.drainDuration += BDArmorySettings.WEAPON_FX_DURATION * (1 - (Distance / 25)); //reduce intake knockout time based on distance from epicenter } } } } ExplosionFx.CreateExplosion(pos, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction, true); } else { ExplosionFx.CreateExplosion(pos, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction); } } } // needs to be Explosiontype Bullet since missile only returns Module MissileLauncher gameObject.SetActive(false); }
public void DetonateIfPossible() { if (!hasDetonated) { hasDetonated = true; // Set hasDetonated here to avoid recursive calls due to ammo boxes exploding each other. var vesselName = vessel != null ? vessel.vesselName : null; Vector3 direction = default(Vector3); GetBlastRadius(); if (CASELevel == 0) //a considerable quantity of explosives and propellants just detonated inside your ship { ExplosionFx.CreateExplosion(part.transform.position, (float)ammoExplosionYield, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, part, vesselName, null, direction); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BD DEBUG] CASE 0 explosion, tntMassEquivilent: " + ammoExplosionYield); } } else if (CASELevel == 1) // the blast is reduced. Damage is severe, but (potentially) survivable { ExplosionFx.CreateExplosion(part.transform.position, ((float)ammoExplosionYield / 2), limitEdexploModelPath, explSoundPath, ExplosionSourceType.Missile, 0, part, vesselName, null, direction, true); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BD DEBUG] CASE I explosion, tntMassEquivilent: " + ammoExplosionYield + ", part: " + part + ", vessel: " + vesselName); } using (var blastHits = Physics.OverlapSphere(part.transform.position, blastRadius / 2, 9076737).AsEnumerable().GetEnumerator()) { while (blastHits.MoveNext()) { if (blastHits.Current == null) { continue; } try { Part partHit = blastHits.Current.GetComponentInParent <Part>(); if (partHit == null || partHit == part) { continue; } if (partHit.mass > 0) { Rigidbody rb = partHit.Rigidbody; if (rb == null) { continue; } Vector3 distToG0 = part.transform.position - partHit.transform.position; Ray LoSRay = new Ray(part.transform.position, partHit.transform.position - part.transform.position); RaycastHit hit; if (Physics.Raycast(LoSRay, out hit, distToG0.magnitude, 9076737)) { if (hit.collider.gameObject != FlightGlobals.currentMainBody.gameObject) { KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); Part p = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>(); if (p == partHit) { ApplyDamage(p, hit); } } } } } catch (Exception e) { Debug.LogError("[ModuleCASE]: Exception in AmmoExplosion Hit" + e.Message); } } } } else //if (CASELevel == 2) //blast contained, shunted out side of hull, minimal damage { ExplosionFx.CreateExplosion(part.transform.position, (float)ammoExplosionYield, shuntExploModelPath, explSoundPath, ExplosionSourceType.Missile, 0, part, vesselName, null, direction, true); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BD DEBUG] CASE II explosion, tntMassEquivilent: " + ammoExplosionYield); } Ray BlastRay = new Ray(part.transform.position, part.transform.up); var hits = Physics.RaycastAll(BlastRay, blastRadius, 9076737); if (hits.Length > 0) { var orderedHits = hits.OrderBy(x => x.distance); using (var hitsEnu = orderedHits.GetEnumerator()) { while (hitsEnu.MoveNext()) { RaycastHit hit = hitsEnu.Current; Part hitPart = null; KerbalEVA hitEVA = null; if (hit.collider.gameObject != FlightGlobals.currentMainBody.gameObject) { try { hitPart = hit.collider.gameObject.GetComponentInParent <Part>(); hitEVA = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); } catch (NullReferenceException) { Debug.Log("[BDArmory]:NullReferenceException for AmmoExplosion Hit"); continue; } if (hitPart == null || hitPart == part) { continue; } if (hitEVA != null) { hitPart = hitEVA.part; if (hitPart.rb != null) { ApplyDamage(hitPart, hit); } break; } ApplyDamage(hitPart, hit); } } } } } this.part.Destroy(); } }
void FixedUpdate() { if (!gameObject.activeInHierarchy) { return; } //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; startPosition -= FloatingOrigin.OffsetNonKrakensbane; } float distanceFromStart = Vector3.Distance(transform.position, startPosition); //calculate flight time for drag purposes flightTimeElapsed += Time.fixedDeltaTime; // calculate flight distance for achievement purposes distanceTraveled += currentVelocity.magnitude * Time.fixedDeltaTime; //Drag types currently only affect Impactvelocity //Numerical Integration is currently Broken switch (dragType) { case BulletDragTypes.None: break; case BulletDragTypes.AnalyticEstimate: CalculateDragAnalyticEstimate(); break; case BulletDragTypes.NumericalIntegration: CalculateDragNumericalIntegration(); break; } if (tracerLength == 0) { // visual tracer velocity is relative to the observer linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()) * tracerDeltaFactor * 0.45f * Time.fixedDeltaTime); } else { linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()).normalized * tracerLength); } if (fadeColor) { FadeColor(); bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance); } linePositions[1] = transform.position; bulletTrail.SetPositions(linePositions); currPosition = transform.position; if (Time.time > timeToLiveUntil) //kill bullet when TTL ends { KillBullet(); return; } // bullet collision block { //reset our hit variables to default state hasPenetrated = true; hasDetonated = false; hasRichocheted = false; penTicker = 0; float dist = currentVelocity.magnitude * Time.fixedDeltaTime; bulletRay = new Ray(currPosition, currentVelocity); var hits = Physics.RaycastAll(bulletRay, dist, 9076737); if (hits.Length > 0) { var orderedHits = hits.OrderBy(x => x.distance); using (var hitsEnu = orderedHits.GetEnumerator()) { while (hitsEnu.MoveNext()) { if (!hasPenetrated || hasRichocheted || hasDetonated) { break; } RaycastHit hit = hitsEnu.Current; Part hitPart = null; KerbalEVA hitEVA = null; try { hitPart = hit.collider.gameObject.GetComponentInParent <Part>(); hitEVA = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); } catch (NullReferenceException) { Debug.Log("[BDArmory]:NullReferenceException for Ballistic Hit"); return; } if (hitEVA != null) { hitPart = hitEVA.part; // relative velocity, separate from the below statement, because the hitpart might be assigned only above if (hitPart?.rb != null) { impactVelocity = (currentVelocity * dragVelocityFactor - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f())).magnitude; } else { impactVelocity = currentVelocity.magnitude * dragVelocityFactor; } ApplyDamage(hitPart, hit, 1, 1); break; } if (hitPart?.vessel == sourceVessel) { continue; //avoid autohit; } Vector3 impactVector = currentVelocity; if (hitPart?.rb != null) { // using relative velocity vector instead of just bullet velocity // since KSP vessels might move faster than bullets impactVector = currentVelocity * dragVelocityFactor - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f()); } float hitAngle = Vector3.Angle(impactVector, -hit.normal); if (CheckGroundHit(hitPart, hit)) { CheckBuildingHit(hit); if (!RicochetScenery(hitAngle)) { ExplosiveDetonation(hitPart, hit, bulletRay); KillBullet(); } else { DoRicochet(hitPart, hit, hitAngle); } return; } //Standard Pipeline Hitpoints, Armor and Explosives impactVelocity = impactVector.magnitude; float anglemultiplier = (float)Math.Cos(Math.PI * hitAngle / 180.0); float penetrationFactor = CalculateArmorPenetration(hitPart, anglemultiplier, hit); if (penetrationFactor >= 2) { //its not going to bounce if it goes right through hasRichocheted = false; } else { if (RicochetOnPart(hitPart, hit, hitAngle, impactVelocity)) { hasRichocheted = true; } } if (penetrationFactor > 1 && !hasRichocheted) //fully penetrated continue ballistic damage { hasPenetrated = true; ApplyDamage(hitPart, hit, 1, penetrationFactor); penTicker += 1; CheckPartForExplosion(hitPart); //Explosive bullets that penetrate should explode shortly after //if penetration is very great, they will have moved on //checking velocity as they would not be able to come out the other side //if (explosive && penetrationFactor < 3 || currentVelocity.magnitude <= 800f) if (explosive) { //move bullet transform.position += (currentVelocity * Time.fixedDeltaTime) / 3; ExplosiveDetonation(hitPart, hit, bulletRay); hasDetonated = true; KillBullet(); } } else if (!hasRichocheted) // explosive bullets that get stopped by armor will explode { //New method if (hitPart.rb != null) { float forceAverageMagnitude = impactVelocity * impactVelocity * (1f / hit.distance) * (bulletMass - tntMass); float accelerationMagnitude = forceAverageMagnitude / (hitPart.vessel.GetTotalMass() * 1000); hitPart?.rb.AddForceAtPosition(impactVector.normalized * accelerationMagnitude, hit.point, ForceMode.Acceleration); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Force Applied " + Math.Round(accelerationMagnitude, 2) + "| Vessel mass in kgs=" + hitPart.vessel.GetTotalMass() * 1000 + "| bullet effective mass =" + (bulletMass - tntMass)); } } hasPenetrated = false; ApplyDamage(hitPart, hit, 1, penetrationFactor); ExplosiveDetonation(hitPart, hit, bulletRay); hasDetonated = true; KillBullet(); } ///////////////////////////////////////////////////////////////////////////////// // penetrated after a few ticks ///////////////////////////////////////////////////////////////////////////////// //penetrating explosive //richochets if ((penTicker >= 2 && explosive) || (hasRichocheted && explosive)) { //detonate ExplosiveDetonation(hitPart, hit, bulletRay, airDetonation); return; } //bullet should not go any further if moving too slowly after hit //smaller caliber rounds would be too deformed to do any further damage if (currentVelocity.magnitude <= 100 && hasPenetrated) { if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Bullet Velocity too low, stopping"); } KillBullet(); return; } //we need to stop the loop if the bullet has stopped,richochet or detonated if (!hasPenetrated || hasRichocheted || hasDetonated) { break; } } //end While } //end enumerator } //end if hits } // end if collision ////////////////////////////////////////////////// //Flak Explosion (air detonation/proximity fuse) ////////////////////////////////////////////////// if (ProximityAirDetonation(distanceFromStart)) { //detonate ExplosionFx.CreateExplosion(currPosition, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, currentVelocity); KillBullet(); return; } if (bulletDrop) { // Gravity??? var gravity_ = FlightGlobals.getGeeForceAtPosition(transform.position); //var gravity_ = Physics.gravity; currentVelocity += gravity_ * TimeWarp.deltaTime; } //move bullet transform.position += currentVelocity * Time.fixedDeltaTime; }
void Detonate(Vector3 pos) { ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, true); Destroy(gameObject); }
void Detonate(Vector3 pos, bool missed) { if (!missed) { if (tntMass > 0) { Vector3 direction = default(Vector3); if (shaped) { direction = (pos + rb.velocity * Time.deltaTime).normalized; } if (concussion || EMP || choker) { using (var hitsEnu = Physics.OverlapSphere(transform.position, 25, 557057).AsEnumerable().GetEnumerator()) { craftHit.Clear(); while (hitsEnu.MoveNext()) { if (hitsEnu.Current == null) { continue; } if (hitsEnu.Current.gameObject == FlightGlobals.currentMainBody.gameObject) { continue; // Ignore terrain hits. } Part partHit = hitsEnu.Current.GetComponentInParent <Part>(); if (craftHit.Contains(partHit.vessel)) { continue; // Don't hit the same craft multiple times. } craftHit.Add(partHit.vessel); float Distance = Vector3.Distance(partHit.transform.position, this.transform.position); if (partHit != null) { if (concussion && partHit.mass > 0) { partHit.rb.AddForceAtPosition((partHit.transform.position - this.transform.position).normalized * impulse, partHit.transform.position, ForceMode.Acceleration); } if (EMP) { var MDEC = partHit.vessel.rootPart.FindModuleImplementing <ModuleDrainEC>(); if (MDEC == null) { MDEC = (ModuleDrainEC)partHit.vessel.rootPart.AddModule("ModuleDrainEC"); } MDEC.incomingDamage += ((25 - Distance) * 5); //this way craft at edge of blast might only get disabled instead of bricked MDEC.softEMP = false; //can bypass EMP damage cap } if (choker) { var ash = partHit.vessel.rootPart.FindModuleImplementing <ModuleDrainIntakes>(); if (ash == null) { ash = (ModuleDrainIntakes)partHit.vessel.rootPart.AddModule("ModuleDrainIntakes"); } ash.drainDuration += BDArmorySettings.WEAPON_FX_DURATION * (1 - (Distance / 25)); //reduce intake knockout time based on distance from epicenter } } } } ExplosionFx.CreateExplosion(pos, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction, true); } else { ExplosionFx.CreateExplosion(pos, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, direction); } if (gravitic) { using (var hitsEnu = Physics.OverlapSphere(transform.position, blastRadius, 557057).AsEnumerable().GetEnumerator()) { while (hitsEnu.MoveNext()) { if (hitsEnu.Current == null) { continue; } Part partHit = hitsEnu.Current.GetComponentInParent <Part>(); if (partHit != null && partHit.mass > 0) { float distance = Vector3.Distance(transform.position, partHit.transform.position); var ME = partHit.vessel.rootPart.FindModuleImplementing <ModuleMassAdjust>(); if (ME == null) { ME = (ModuleMassAdjust)partHit.vessel.rootPart.AddModule("ModuleMassAdjust"); } ME.massMod += (massMod * (1 - (distance / blastRadius))); //this way craft at edge of blast might only get disabled instead of bricked ME.duration += (BDArmorySettings.WEAPON_FX_DURATION * (1 - (distance / blastRadius))); //can bypass EMP damage cap } } } } } } // needs to be Explosiontype Bullet since missile only returns Module MissileLauncher gameObject.SetActive(false); }
void Detonate() //borrowed from Stockalike Project Orion { if (hasDetonated || FlightGlobals.currentMainBody == null || VesselSpawner.Instance.vesselsSpawning) // Don't trigger on scene changes or during spawning. { return; } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory.NukeTest]: Running Detonate() on nerva in vessel " + Sourcevessel); } //affect any nearby parts/vessels that aren't the source vessel Dictionary <string, int> vesselsHitByMissiles = new Dictionary <string, int>(); using (var blastHits = Physics.OverlapSphere(part.transform.position, thermalRadius, 9076737).AsEnumerable().GetEnumerator()) { partsHit.Clear(); while (blastHits.MoveNext()) { if (blastHits.Current == null) { continue; } if (blastHits.Current.gameObject == FlightGlobals.currentMainBody.gameObject) { continue; // Ignore terrain hits. } Part partHit = blastHits.Current.GetComponentInParent <Part>(); if (partsHit.Contains(partHit)) { continue; // Don't hit the same part multiple times. } partsHit.Add(partHit); if (partHit != null && partHit.mass > 0) { var distToG0 = Math.Max((part.transform.position - partHit.transform.position).magnitude, 1f); float radiativeArea = !double.IsNaN(partHit.radiativeArea) ? (float)partHit.radiativeArea : partHit.GetArea(); if (BDArmorySettings.DRAW_DEBUG_LABELS && double.IsNaN(partHit.radiativeArea)) { Debug.Log("[BDArmory.NukeTest]: radiative area of part " + partHit + " was NaN, using approximate area " + radiativeArea + " instead."); } //if (partHit.vessel != this.vessel) if (partHit != part) { partHit.skinTemperature += fluence * 3370000000 / (4 * Math.PI * Math.Pow(distToG0, 2.0)) * radiativeArea / 2; // Fluence scales linearly w/ yield, 1 Kt will produce between 33 TJ and 337 kJ at 0-1000m, } // everything gets heated via atmosphere Ray LoSRay = new Ray(part.transform.position, partHit.transform.position - part.transform.position); RaycastHit hit; if (Physics.Raycast(LoSRay, out hit, distToG0, 9076737)) // only add impulse to parts with line of sight to detonation { KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); Part p = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>(); float blastDamage = 100; if (p == partHit) { //if (p.vessel != this.vessel) if (p != part) { // Forces if (p.rb != null && p.rb.mass > 0) // Don't apply forces to physicsless parts. { var blastImpulse = Mathf.Pow(3.01f * 1100f / distToG0, 1.25f) * 6.894f * lastValidAtmDensity * yieldCubeRoot * radiativeArea / 3f; // Math.Pow(Math.Pow(Math.Pow(9.54e-3 * 2200.0 / distToG0, 1.95), 4.0) + Math.Pow(Math.Pow(3.01 * 1100.0 / distToG0, 1.25), 4.0), 0.25) * 6.894 * vessel.atmDensity * Math.Pow(yield, 1.0 / 3.0) * partHit.radiativeArea / 3.0; //assuming a 0.05 kT yield if (float.IsNaN(blastImpulse)) { Debug.LogWarning("[BDArmory.NukeTest]: blast impulse is NaN. distToG0: " + distToG0 + ", vessel: " + vessel + ", atmDensity: " + lastValidAtmDensity + ", yield^(1/3): " + yieldCubeRoot + ", partHit: " + partHit + ", radiativeArea: " + radiativeArea); } else { if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory.NukeTest]: Applying " + blastImpulse.ToString("0.0") + " impulse to " + p + " of mass " + p.mass + " at distance " + distToG0 + "m"); } p.rb.AddForceAtPosition((partHit.transform.position - part.transform.position).normalized * (float)blastImpulse, partHit.transform.position, ForceMode.Impulse); } } // Damage blastDamage = ((float)((yield * 3370000000) / (4f * Mathf.PI * distToG0 * distToG0) * (radiativeArea / 2f))); if (float.IsNaN(blastDamage)) { Debug.LogWarning("[BDArmory.NukeTest]: blast damage is NaN. distToG0: " + distToG0 + ", yield: " + yield + ", part: " + partHit + ", radiativeArea: " + radiativeArea); continue; } p.AddExplosiveDamage(blastDamage, 100, ExplosionSourceType.Missile); // Scoring var aName = Sourcevessel; // Attacker var tName = p.vessel.GetName(); // Target if (tName != null && aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(tName) && BDACompetitionMode.Instance.Scores.ContainsKey(aName)) { // Part hit counts if (BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts.ContainsKey(aName)) { ++BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts[aName]; } else { BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts[aName] = 1; } if (!BDACompetitionMode.Instance.Scores[tName].everyoneWhoHitMeWithMissiles.Contains(aName)) { BDACompetitionMode.Instance.Scores[tName].everyoneWhoHitMeWithMissiles.Add(aName); } ++BDACompetitionMode.Instance.Scores[aName].totalDamagedPartsDueToMissiles; BDACompetitionMode.Instance.Scores[tName].lastMissileHitTime = Planetarium.GetUniversalTime(); BDACompetitionMode.Instance.Scores[tName].lastPersonWhoHitMeWithAMissile = aName; if (vesselsHitByMissiles.ContainsKey(tName)) { ++vesselsHitByMissiles[tName]; } else { vesselsHitByMissiles[tName] = 1; } if (BDArmorySettings.REMOTE_LOGGING_ENABLED) { BDAScoreService.Instance.TrackMissileParts(aName, tName, 1); } // Part damage scoring var tData = BDACompetitionMode.Instance.Scores[tName]; if (tData.damageFromMissiles.ContainsKey(aName)) { tData.damageFromMissiles[aName] += blastDamage; } else { tData.damageFromMissiles.Add(aName, blastDamage); } if (BDArmorySettings.REMOTE_LOGGING_ENABLED) { BDAScoreService.Instance.TrackMissileDamage(aName, tName, blastDamage); } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory.NukeTest]: " + aName + " did " + blastDamage + " blast damage to " + tName + " at " + distToG0.ToString("0.000") + "m"); } } } } } } else { DestructibleBuilding building = blastHits.Current.GetComponentInParent <DestructibleBuilding>(); if (building != null) { var distToEpicenter = Mathf.Max((part.transform.position - building.transform.position).magnitude, 1f); var blastImpulse = Mathf.Pow(3.01f * 1100f / distToEpicenter, 1.25f) * 6.894f * lastValidAtmDensity * yieldCubeRoot; // blastImpulse = (((((Math.Pow((Math.Pow((Math.Pow((9.54 * Math.Pow(10.0, -3.0) * (2200.0 / distToEpicenter)), 1.95)), 4.0) + Math.Pow((Math.Pow((3.01 * (1100.0 / distToEpicenter)), 1.25)), 4.0)), 0.25)) * 6.894) * (vessel.atmDensity)) * Math.Pow(yield, (1.0 / 3.0)))); if (!double.IsNaN(blastImpulse) && blastImpulse > 140) //140kPa, level at which reinforced concrete structures are destroyed { building.Demolish(); } } } } } if (vesselsHitByMissiles.Count > 0) { string message = ""; foreach (var vesselName in vesselsHitByMissiles.Keys) { message += (message == "" ? "" : " and ") + vesselName + " had " + vesselsHitByMissiles[vesselName]; } message += " parts damaged (Blast Wave) by " + Sourcevessel + "'s exploding engine core."; BDACompetitionMode.Instance.competitionStatus.Add(message); Debug.Log("[BDArmory.NukeTest]: " + message); } ExplosionFx.CreateExplosion(part.transform.position, 1, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, null, Sourcevessel, "Reactor Containment Failure"); hasDetonated = true; if (part.vessel != null) // Already in the process of being destroyed. { part.Destroy(); } }
public void Explode() { Color white = new Color(1, 1, 1, 1); Color whitef = new Color(1, 1, 1, 0); weapon.vessel.GetHeightFromTerrain(); blastRadius = weapon.blastRadius; blastPower = weapon.blastPower; blastHeat = weapon.blastHeat; Vector3 position = transform.position; Vector3 direction = transform.up; Quaternion rotation = Quaternion.LookRotation(VectorUtils.GetUpDirection(position)); if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain >= 70000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject lightBall = new GameObject(); lightBall.SetActive(true); lightBall.transform.position = position; lightBall.transform.rotation = rotation; Detonator sdetonator = lightBall.AddComponent <Detonator>(); lightBall.GetComponent <Detonator>().enabled = true; sdetonator.duration = 2f; sdetonator.size = blastRadius; sdetonator.detail = 10f; Debug.Log("Space Explosion Activated"); } else { if (!hasExploded && weapon.vessel.heightFromTerrain <= 69999 && weapon.vessel.heightFromTerrain >= 501 && weapon.TimeFired >= weapon.dropTime && weapon.blastRadius >= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject source = new GameObject(); source.SetActive(true); source.transform.position = position; source.transform.rotation = rotation; source.transform.up = direction; ///Detonator ndetonator = source.AddComponent<Detonator>(); //source.GetComponent<Detonator>().enabled = true; //ndetonator.duration = 5.0f; //ndetonator.size = blastRadius; //ndetonator.detail = 10.0f; CameraFade flashEffect = source.AddComponent <CameraFade>(); source.GetComponent <CameraFade>().enabled = true; flashEffect.SetScreenOverlayColor(white); flashEffect.StartFade(whitef, 2.0f); ExplosionFx.CreateExplosion(position, blastPower, explAirPath, explSoundPath, isMissile = true, caliber = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Air NExplosion Activated"); } else { if (!hasExploded && weapon.vessel.heightFromTerrain <= 69999 && weapon.vessel.heightFromTerrain >= 501 && weapon.TimeFired >= weapon.dropTime && weapon.blastRadius <= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject csource = new GameObject(); csource.SetActive(true); csource.transform.position = position; csource.transform.rotation = rotation; csource.transform.up = direction; //Detonator cdetonator = csource.AddComponent<Detonator>(); //csource.GetComponent<Detonator>().enabled = true; //cdetonator.duration = 3.0f; //cdetonator.size = blastRadius; //cdetonator.detail = 10.0f; ExplosionFx.CreateExplosion(position, blastPower, explAirPath, explSoundPath, isMissile = true, caliber = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Air CExplosion Activated"); } else { if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain <= 500 && weapon.blastRadius >= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject source = new GameObject(); source.SetActive(true); source.transform.position = position; source.transform.rotation = rotation; source.transform.up = direction; //Detonator ndetonator = source.AddComponent<Detonator>(); //source.GetComponent<Detonator>().enabled = true; //ndetonator.duration = 5.0f; //ndetonator.size = blastRadius; //ndetonator.detail = 10.0f; CameraFade flashEffect = source.AddComponent <CameraFade>(); source.GetComponent <CameraFade>().enabled = true; flashEffect.SetScreenOverlayColor(white); flashEffect.StartFade(whitef, 2.0f); ExplosionFx.CreateExplosion(position, blastPower, explGroundPath, explSoundPath, isMissile = true, caliber = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Ground NExplosion Activated"); } else { if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain <= 500 && weapon.blastRadius <= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject csource = new GameObject(); csource.SetActive(true); csource.transform.position = position; csource.transform.rotation = rotation; csource.transform.up = direction; //Detonator cdetonator = csource.AddComponent<Detonator>(); //csource.GetComponent<Detonator>().enabled = true; //cdetonator.duration = 3.0f; //cdetonator.size = blastRadius; //cdetonator.detail = 10.0f; ExplosionFx.CreateExplosion(position, blastPower, explGroundPath, explSoundPath, isMissile = true, caliber = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Ground CExplosion Activated"); } } } } } }
public void Explode() { weapon.vessel.GetHeightFromTerrain(); Vector3 position = transform.position; Quaternion rotation = Quaternion.LookRotation(VectorUtils.GetUpDirection(position)); Vector3 direction = transform.up; blastRadius = weapon.blastRadius; blastPower = weapon.blastPower; blastTemperature = weapon.blastHeat; if (!hasExploded && weapon.vessel.heightFromTerrain >= 72000 && weapon.TimeFired >= weapon.dropTime && weapon.blastRadius >= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } ExplosionFx.CreateExplosion(position, blastPower, explSpacePath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Space explosion confirmed"); } else { if (!hasExploded && weapon.vessel.altitude <= 0 && weapon.TimeFired >= weapon.dropTime) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject source = new GameObject(); source.SetActive(true); source.transform.position = position; source.transform.rotation = rotation; source.transform.up = direction; ExplosionFx.CreateExplosion(position, blastPower, explWaterPath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Underwater explosion confirmed"); } else { if (!hasExploded && weapon.vessel.heightFromTerrain <= 50000 && weapon.vessel.heightFromTerrain >= 501 && weapon.TimeFired >= weapon.dropTime && weapon.blastRadius >= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject source = new GameObject(); source.SetActive(true); source.transform.position = position; source.transform.rotation = rotation; source.transform.up = direction; ExplosionFx.CreateExplosion(position, blastPower, explAirPath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Air explosion confirmed"); } else { if (!hasExploded && weapon.vessel.heightFromTerrain <= 60000 && weapon.vessel.heightFromTerrain >= 501 && weapon.TimeFired >= weapon.dropTime && weapon.blastRadius <= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject csource = new GameObject(); csource.SetActive(true); csource.transform.position = position; csource.transform.rotation = rotation; csource.transform.up = direction; ExplosionFx.CreateExplosion(position, blastPower, explAirPath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Air explosion confirmed"); } else { if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain <= 450 && weapon.blastRadius >= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject source = new GameObject(); source.SetActive(true); source.transform.position = position; source.transform.rotation = rotation; source.transform.up = direction; ExplosionFx.CreateExplosion(position, blastPower, explGroundPath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Ground explosion confirmed"); } else { if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain <= 250 && weapon.blastRadius <= 1000) { hasExploded = true; if (part != null) { part.temperature = part.maxTemp + 100; } GameObject csource = new GameObject(); csource.SetActive(true); csource.transform.position = position; csource.transform.rotation = rotation; csource.transform.up = direction; ExplosionFx.CreateExplosion(position, blastPower, explGroundPath, explSoundPath, Missile = true, bullets = 0, explosivePart = null, direction = default(Vector3)); Debug.Log("Ground explosion confirmed"); } } } } } } }
void Detonate(Vector3 pos) { ExplosionFx.CreateExplosion(pos, blastForce, subExplModelPath, subExplSoundPath, ExplosionSourceType.Missile, 0, null, sourceVesselName); Destroy(gameObject); }