예제 #1
0
 static void UpdateActiveBlastwave()
 {
     for (int i = 0; i < activeBlastwaveObjects.Count; ++i)
     {
         Blastwave exp = activeBlastwaveObjects[i];
         exp.Simulate();
     }
 }
예제 #2
0
 void FixedUpdate()
 {
     if (FlightGlobals.ready)
     {
         explosiveHandler.UpdateFreeReactantsAndReactions();
         Blastwave.SimulateActiveBlastwaves();
     }
 }
예제 #3
0
        void Start()
        {
            Blastwave.Setup();

            explosiveHandler = new ExplosiveReactions();
            GameEvents.onPartDestroyed.Add(CreateExplosion);
            GameEvents.onPartUnpack.Add(SetExplosionPotential);
        }
예제 #4
0
 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;
 }
예제 #5
0
        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);
        }
예제 #6
0
        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
        }
예제 #7
0
        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);
                    }
                }
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
                    }
                }
            }
        }