Пример #1
0
        void Detonate(Vector3 pos)
        {
            BDArmorySettings.numberOfParticleEmitters--;

            ExplosionFX.CreateExplosion(pos, blastRadius, blastForce, blastHeat, sourceVessel, rb.velocity.normalized,
                                        explModelPath, explSoundPath);

            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
        }
Пример #2
0
        public void CreateExplosion(Part part)
        {
            float explodeScale = 0;
            IEnumerator <PartResource> resources = part.Resources.GetEnumerator();

            while (resources.MoveNext())
            {
                if (resources.Current == null)
                {
                    continue;
                }
                switch (resources.Current.resourceName)
                {
                case "LiquidFuel":
                    explodeScale += (float)resources.Current.amount;
                    break;

                case "Oxidizer":
                    explodeScale += (float)resources.Current.amount;
                    break;
                }
            }
            resources.Dispose();
            explodeScale /= 100;
            part.explode();
            ExplosionFX.CreateExplosion(part.partTransform.position, explodeScale * blastRadius, explodeScale * blastPower * 2,
                                        explodeScale * blastHeat, part.vessel, FlightGlobals.upAxis, explModelPath, explSoundPath);
        }
Пример #3
0
        private void Detonate()
        {
            if (part != null)
            {
                part.SetDamage(part.maxTemp * 2);
            }
            Vector3 position = part.vessel.CoM;

            ExplosionFX.CreateExplosion(position, blastRadius, blastPower, blastHeat, vessel, FlightGlobals.getUpAxis(),
                                        "BDArmory/Models/explosion/explosionLarge", "BDArmory/Sounds/explode1");
        }
Пример #4
0
        void FixedUpdate()
        {
            float distanceFromStartSqr = (transform.position - startPosition).sqrMagnitude;

            if (!gameObject.activeInHierarchy)
            {
                return;
            }
            flightTimeElapsed += TimeWarp.fixedDeltaTime; //calculate flight time for drag purposes

            if (bulletDrop && FlightGlobals.RefFrameIsRotating)
            {
                currentVelocity += FlightGlobals.getGeeForceAtPosition(transform.position) * TimeWarp.fixedDeltaTime;
            }
            if (dragType == BulletDragTypes.NumericalIntegration)
            {
                Vector3 dragAcc = currentVelocity * currentVelocity.magnitude *
                                  (float)
                                  FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position),
                                                              FlightGlobals.getExternalTemperature(transform.position));
                dragAcc *= 0.5f;
                dragAcc /= ballisticCoefficient;

                currentVelocity -= dragAcc * TimeWarp.fixedDeltaTime;
                //numerical integration; using Euler is silly, but let's go with it anyway
            }


            if (tracerLength == 0)
            {
                bulletTrail.SetPosition(0,
                                        transform.position +
                                        (currentVelocity * tracerDeltaFactor * TimeWarp.fixedDeltaTime / TimeWarp.CurrentRate) -
                                        (FlightGlobals.ActiveVessel.Velocity() * TimeWarp.fixedDeltaTime));
            }
            else
            {
                bulletTrail.SetPosition(0,
                                        transform.position + ((currentVelocity - sourceOriginalV).normalized * tracerLength));
            }
            if (fadeColor)
            {
                FadeColor();
                bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance);
            }


            bulletTrail.SetPosition(1, transform.position);


            currPosition = gameObject.transform.position;

            if (distanceFromStartSqr > maxDistance * maxDistance)
            {
                //GameObject.Destroy(gameObject);
                KillBullet();
                return;
            }

            if (collisionEnabled)
            {
                float dist = initialSpeed * TimeWarp.fixedDeltaTime;

                Ray        ray = new Ray(prevPosition, currPosition - prevPosition);
                RaycastHit hit;
                try
                {
                    if (Physics.Raycast(ray, out hit, dist, 688129))
                    {
                        bool penetrated = true;
                        bool hitEva     = false;
                        Part hitPart    = null; //determine when bullet collides with a target
                        try
                        {
                            // Look for any Kerbal first. The part, KerbalEVA, is functionally similar to regular parts.
                            KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>();
                            hitPart = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>();
                            hitEva  = eva;
                        }
                        catch (NullReferenceException)
                        {
                        }
                        // Need to make sure Kerbals don't get armor.
                        BDArmor armor = hitEva ? null : BDArmor.GetArmor(hit.collider, hitPart);
                        ArmorPenetration.BulletPenetrationData armorData = new ArmorPenetration.BulletPenetrationData(ray, hit);
                        ArmorPenetration.DoPenetrationRay(armorData, bullet.positiveCoefficient);
                        float penetration      = bullet.penetration.Evaluate(Mathf.Sqrt(distanceFromStartSqr)) / 1000;
                        bool  fulllyPenetrated = penetration * leftPenetration >
                                                 ((armor == null) ? 1f : armor.EquivalentThickness) * armorData.armorThickness;
                        Vector3 finalDirect = Vector3.Lerp(ray.direction, -hit.normal, bullet.positiveCoefficient);


                        if (fulllyPenetrated)
                        {
                            currentVelocity = finalDirect * currentVelocity.magnitude * leftPenetration;
                        }
                        else
                        {
                            currPosition = hit.point;
                            bulletTrail.SetPosition(1, currPosition);
                        }
                        float hitAngle = Vector3.Angle(currentVelocity, -hit.normal);

                        if (bulletType != PooledBulletTypes.Explosive) //dont do bullet damage if it is explosive
                        {
                            float impactVelocity = currentVelocity.magnitude;
                            if (dragType == BulletDragTypes.AnalyticEstimate)
                            {
                                float analyticDragVelAdjustment =
                                    (float)
                                    FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(currPosition),
                                                                FlightGlobals.getExternalTemperature(currPosition));
                                analyticDragVelAdjustment *= flightTimeElapsed * initialSpeed;
                                analyticDragVelAdjustment += 2 * ballisticCoefficient;

                                analyticDragVelAdjustment = 2 * ballisticCoefficient * initialSpeed / analyticDragVelAdjustment;
                                //velocity as a function of time under the assumption of a projectile only acted upon by drag with a constant drag area

                                analyticDragVelAdjustment = analyticDragVelAdjustment - initialSpeed;
                                //since the above was velocity as a function of time, but we need a difference in drag, subtract the initial velocity
                                //the above number should be negative...
                                impactVelocity += analyticDragVelAdjustment; //so add it to the impact velocity

                                if (impactVelocity < 0)
                                {
                                    impactVelocity = 0;
                                    //clamp the velocity to > 0, since it could drop below 0 if the bullet is fired upwards
                                }
                                //Debug.Log("flight time: " + flightTimeElapsed + " BC: " + ballisticCoefficient + "\ninit speed: " + initialSpeed + " vel diff: " + analyticDragVelAdjustment);
                            }

                            //hitting a vessel Part

                            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                            /////////////////////////////////////////////////[panzer1b] HEAT BASED DAMAGE CODE START//////////////////////////////////////////////////////////////
                            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


                            if (hitPart != null) //see if it will ricochet of the part
                            {
                                penetrated = !RicochetOnPart(hitPart, hitAngle, impactVelocity);
                            }
                            else //see if it will ricochet off scenery
                            {
                                float reflectRandom = UnityEngine.Random.Range(-75f, 90f);
                                if (reflectRandom > 90 - hitAngle)
                                {
                                    penetrated = false;
                                }
                            }


                            if (hitPart != null && !hitPart.partInfo.name.Contains("Strut"))
                            //when a part is hit, execute damage code (ignores struts to keep those from being abused as armor)(no, because they caused weird bugs :) -BahamutoD)
                            {
                                float heatDamage = (mass / (hitPart.crashTolerance * hitPart.mass)) * impactVelocity *
                                                   impactVelocity * BDArmorySettings.DMG_MULTIPLIER *
                                                   bulletDmgMult
                                ;
                                //how much heat damage will be applied based on bullet mass, velocity, and part's impact tolerance and mass
                                if (!penetrated)
                                {
                                    heatDamage = heatDamage / 8;
                                }
                                if (fulllyPenetrated)
                                {
                                    heatDamage /= 8;
                                }
                                if (BDArmorySettings.INSTAKILL)
                                //instakill support, will be removed once mod becomes officially MP
                                {
                                    heatDamage = (float)hitPart.maxTemp + 100;
                                    //make heat damage equal to the part's max temperture, effectively instakilling any part it hits
                                }
                                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                {
                                    Debug.Log("[BDArmory]: Hit! damage applied: " + heatDamage); //debugging stuff
                                }
                                if (hitPart.vessel != sourceVessel)
                                {
                                    hitPart.AddDamage(heatDamage);
                                }

                                float overKillHeatDamage = (float)(hitPart.temperature - hitPart.maxTemp);

                                if (overKillHeatDamage > 0)
                                //if the part is destroyed by overheating, we want to add the remaining heat to attached parts.  This prevents using tiny parts as armor
                                {
                                    overKillHeatDamage *= hitPart.crashTolerance; //reset to raw damage
                                    float numConnectedParts = hitPart.children.Count;
                                    if (hitPart.parent != null)
                                    {
                                        numConnectedParts++;
                                        overKillHeatDamage /= numConnectedParts;
                                        hitPart.parent.AddDamage(overKillHeatDamage /
                                                                 (hitPart.parent.crashTolerance * hitPart.parent.mass));

                                        for (int i = 0; i < hitPart.children.Count; i++)
                                        {
                                            hitPart.children[i].AddDamage(overKillHeatDamage /
                                                                          hitPart.children[i].crashTolerance);
                                        }
                                    }
                                    else
                                    {
                                        overKillHeatDamage /= numConnectedParts;
                                        for (int i = 0; i < hitPart.children.Count; i++)
                                        {
                                            hitPart.children[i].AddDamage(overKillHeatDamage /
                                                                          hitPart.children[i].crashTolerance);
                                        }
                                    }
                                }
                            }

                            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                            /////////////////////////////////////////////////[panzer1b] HEAT BASED DAMAGE CODE END////////////////////////////////////////////////////////////////
                            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


                            //hitting a Building
                            DestructibleBuilding hitBuilding = null;
                            try
                            {
                                hitBuilding = hit.collider.gameObject.GetComponentUpwards <DestructibleBuilding>();
                            }
                            catch (NullReferenceException)
                            {
                            }
                            if (hitBuilding != null && hitBuilding.IsIntact)
                            {
                                float damageToBuilding = mass * initialSpeed * initialSpeed * BDArmorySettings.DMG_MULTIPLIER /
                                                         12000;
                                if (!penetrated)
                                {
                                    damageToBuilding = damageToBuilding / 8;
                                }
                                hitBuilding.AddDamage(damageToBuilding);
                                if (hitBuilding.Damage > hitBuilding.impactMomentumThreshold)
                                {
                                    hitBuilding.Demolish();
                                }
                                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                {
                                    Debug.Log("[BDArmory]: bullet hit destructible building! Damage: " +
                                              (damageToBuilding).ToString("0.00") + ", total Damage: " + hitBuilding.Damage);
                                }
                            }
                        }

                        if (hitPart == null || (hitPart != null && hitPart.vessel != sourceVessel))
                        {
                            if (!penetrated && !hasBounced && !fulllyPenetrated)
                            {
                                //ricochet
                                hasBounced = true;
                                if (BDArmorySettings.BULLET_HITS)
                                {
                                    BulletHitFX.CreateBulletHit(hit.point, hit.normal, true);
                                }

                                tracerStartWidth /= 2;
                                tracerEndWidth   /= 2;

                                transform.position = hit.point;
                                currentVelocity    = Vector3.Reflect(currentVelocity, hit.normal);
                                currentVelocity    = (hitAngle / 150) * currentVelocity * 0.65f;

                                Vector3 randomDirection = UnityEngine.Random.rotation * Vector3.one;

                                currentVelocity = Vector3.RotateTowards(currentVelocity, randomDirection,
                                                                        UnityEngine.Random.Range(0f, 5f) * Mathf.Deg2Rad, 0);
                            }
                            else
                            {
                                if (bulletType == PooledBulletTypes.Explosive)
                                {
                                    ExplosionFX.CreateExplosion(hit.point - (ray.direction * 0.1f), radius, blastPower,
                                                                blastHeat, sourceVessel, currentVelocity.normalized, explModelPath, explSoundPath);
                                }
                                else if (BDArmorySettings.BULLET_HITS)
                                {
                                    BulletHitFX.CreateBulletHit(hit.point, hit.normal, false);
                                }


                                if (armor != null &&
                                    (penetration * leftPenetration > armor.outerArmorThickness / 1000 * armor.EquivalentThickness ||
                                     fulllyPenetrated))
                                {
                                    switch (armor.explodeMode)
                                    {
                                    case BDArmor.ExplodeMode.Always:
                                        armor.CreateExplosion(hitPart);
                                        break;

                                    case BDArmor.ExplodeMode.Dynamic:
                                        float probability = CalculateExplosionProbability(hitPart);
                                        if (probability > 0.1f)
                                        {
                                            armor.CreateExplosion(hitPart);
                                        }
                                        break;

                                    case BDArmor.ExplodeMode.Never:
                                        break;
                                    }
                                }
                                if (fulllyPenetrated)
                                {
                                    leftPenetration   -= armorData.armorThickness / penetration;
                                    transform.position = armorData.hitResultOut.point;
                                    flightTimeElapsed -= Time.fixedDeltaTime;
                                    prevPosition       = transform.position;
                                    FixedUpdate();
                                    return;
                                }
                                else
                                {
                                    KillBullet();
                                    return;
                                }
                            }
                        }
                    }
                } catch (NullReferenceException e) // Exception handling
                {
                    Debug.Log("[BDArmory]: Ran afoul of exception filter\n" + e.StackTrace);
                }
            }

            if (bulletType == PooledBulletTypes.Explosive && airDetonation && distanceFromStartSqr > detonationRange * detonationRange)
            {
                //detonate
                ExplosionFX.CreateExplosion(transform.position, radius, blastPower, blastHeat, sourceVessel,
                                            currentVelocity.normalized, explModelPath, explSoundPath);
                //GameObject.Destroy(gameObject); //destroy bullet on collision
                KillBullet();
                return;
            }


            prevPosition = currPosition;

            //move bullet
            transform.position += currentVelocity * Time.fixedDeltaTime;
        }
Пример #5
0
 void Detonate(Vector3 pos)
 {
     ExplosionFX.CreateExplosion(pos, blastRadius, blastForce, blastHeat, sourceVessel, FlightGlobals.getUpAxis(),
                                 subExplModelPath, subExplSoundPath);
     Destroy(gameObject); //destroy bullet on collision
 }