static void UpdateActiveBlastwave() { for (int i = 0; i < activeBlastwaveObjects.Count; ++i) { Blastwave exp = activeBlastwaveObjects[i]; exp.Simulate(); } }
void FixedUpdate() { if (FlightGlobals.ready) { explosiveHandler.UpdateFreeReactantsAndReactions(); Blastwave.SimulateActiveBlastwaves(); } }
void Start() { Blastwave.Setup(); explosiveHandler = new ExplosiveReactions(); GameEvents.onPartDestroyed.Add(CreateExplosion); GameEvents.onPartUnpack.Add(SetExplosionPotential); }
static void UpdateWorldLocations() { for (int i = 0; i < activeBlastwaveObjects.Count; ++i) { Blastwave exp = activeBlastwaveObjects[i]; if (floatingOrigin != FloatingOrigin.Offset) { exp.worldLocation += (FloatingOrigin.Offset - floatingOrigin); } exp.worldLocation -= Krakensbane.GetFrameVelocity(); } floatingOrigin = FloatingOrigin.Offset; }
public static void CreateBlastwave(float yield, float maxOverPres, float impulseFactor, Vector3d worldLocation) { if (!ready) { Setup(); } Blastwave newExplosion; if (inactiveBlastwaveObjects.Count > 0) { newExplosion = inactiveBlastwaveObjects.Dequeue(); } else { newExplosion = new Blastwave(); } newExplosion.SetConditionsAndInitiate(yield, maxOverPres, impulseFactor, worldLocation); }
void CreateExplosion(ExplosiveReaction reaction, FreeReactant reactant1, FreeReactant reactant2) { double reactantRatio = reaction.reactantRatios[reactant1.resource.id] / reaction.reactantRatios[reactant2.resource.id]; double reactant1Amount = reactant1.resourceMass; double reactant2Amount = reactant2.resourceMass; double fuelOxRatio = reactant2Amount * reactantRatio / reactant1Amount; if (fuelOxRatio > 1) //means there is more reactant 2 than is needed { reactant2Amount = reactant1Amount / reactantRatio; //amount of reactant2 needed for reaction reactant1.resourceMass -= reactant1Amount; //remove this from FreeReactant reactant2.resourceMass -= reactant2Amount; } else { reactant1Amount = reactant2Amount * reactantRatio; //amount of reactant2 needed for reaction reactant1.resourceMass -= reactant1Amount; //remove this from FreeReactant reactant2.resourceMass -= reactant2Amount; } Vector3d avgVel = reactant1.worldVelocity * reactant1Amount + reactant2.worldVelocity * reactant2Amount; avgVel /= reactant1Amount + reactant2Amount; double fractionTNTEquivalent = reaction.PYROYieldCurve.Evaluate((float)avgVel.magnitude) * 4.184e6 * (reactant1Amount + reactant2Amount); Vector3d avgPos = reactant1.worldPosition * reactant1Amount + reactant2.worldPosition * reactant2Amount; avgPos /= reactant1Amount + reactant2Amount; Debug.Log("[Blastwave]: Create Explosion with yield of " + fractionTNTEquivalent + " J"); //create blastwave Blastwave.CreateBlastwave((float)fractionTNTEquivalent, reaction.maxOverPreskPa, reaction.impulseFactor, avgPos); //create fireball //TODO fireball call }
static void UpdateCoalesence() { for (int i = 0; i < activeBlastwaveObjects.Count; ++i) { Blastwave exp = activeBlastwaveObjects[i]; if (exp.yield <= 0.001f) { continue; } for (int j = 0; j < activeBlastwaveObjects.Count; ++j) { if (i == j) { continue; } Blastwave otherExp = activeBlastwaveObjects[j]; float dist = exp.potentialCoalesenceCandidates[otherExp]; float mergeRadius = dist * 10f; if (exp.currentBlastRadius > mergeRadius && otherExp.currentBlastRadius > mergeRadius) { float percentDiffBlastRadius = 2 * (exp.currentBlastRadius - otherExp.currentBlastRadius) / (exp.currentBlastRadius + otherExp.currentBlastRadius); percentDiffBlastRadius = Math.Abs(percentDiffBlastRadius); if (percentDiffBlastRadius > 0.05f) { continue; } //Debug.Log("Merging explosions of yield " + exp.equivalentTNTMass + " and " + otherExp.equivalentTNTMass + " due to proximity\n"); float yieldChange = otherExp.yield; exp.UpdateYield(yieldChange, otherExp.worldLocation); otherExp.UpdateYield(-yieldChange, otherExp.worldLocation); } } } }
void SetConditionsAndInitiate(float yield, float maxOverPres, float impulseFactor, Vector3d worldLocation) { this.yield = yield; this.equivalentTNTMass = this.yield * JOULE_TO_KG_TNT_CONVERSION; this.equivTNTMassInvCubeRoot = (float)Math.Pow(this.equivalentTNTMass, -(1f / 3f)); this.worldLocation = worldLocation; this.atmPres = FlightGlobals.getStaticPressure(this.worldLocation); this.ambientSoundSpeed = FlightGlobals.currentMainBody.GetSpeedOfSound(this.atmPres, FlightGlobals.currentMainBody.GetDensity(this.atmPres, FlightGlobals.currentMainBody.GetTemperature(FlightGlobals.currentMainBody.GetAltitude(worldLocation)))); this.ratioSpecHeat = FlightGlobals.currentMainBody.atmosphereAdiabaticIndex; if (atmPres <= 0 || ambientSoundSpeed <= 0) { return; } this.maxOverPres = maxOverPres; this.impulseFactor = impulseFactor; this.currentPeakPressure = (maxOverPres + 1f) * (float)atmPres; this.currentPosImpulse = peakPosImpulse; this.currentBlastRadius = 0; this.blastWaveVel = 0; this.prevPeakPressure = this.currentPeakPressure; this.prevPosImpulse = this.currentPosImpulse; this.prevBlastRadius = 0; for (int i = 0; i < activeBlastwaveObjects.Count; i++) { Blastwave otherExplosion = activeBlastwaveObjects[i]; float dist = (otherExplosion.worldLocation - this.worldLocation).magnitude; otherExplosion.potentialCoalesenceCandidates.Add(this, dist); this.potentialCoalesenceCandidates.Add(otherExplosion, dist); } activeBlastwaveObjects.Add(this); }
static void CheckFinishedBlastwave() { for (int i = 0; i < activeBlastwaveObjects.Count; ++i) { Blastwave exp = activeBlastwaveObjects[i]; if (exp.CheckSimCompleted()) { activeBlastwaveObjects.RemoveAt(i); --i; if (inactiveBlastwaveObjects.Count < BASELINE_EXPLOSION_COUNT) { inactiveBlastwaveObjects.Enqueue(exp); } exp.potentialCoalesenceCandidates.Clear(); for (int j = 0; j < activeBlastwaveObjects.Count; ++j) { activeBlastwaveObjects[j].potentialCoalesenceCandidates.Remove(exp); } } } }