Beispiel #1
0
        public void Update(float dt)
        {
            if (m_queuedExplosions.Count <= 0)
            {
                return;
            }
            int x = m_queuedExplosions[0].X;
            int y = m_queuedExplosions[0].Y;
            int z = m_queuedExplosions[0].Z;

            m_pressureByPoint            = new SparseSpatialArray <float>(x, y, z, 0f);
            m_surroundingPressureByPoint = new SparseSpatialArray <SurroundingPressurePoint>(x, y, z, new SurroundingPressurePoint
            {
                IsIncendiary = false,
                Pressure     = 0f
            });
            m_projectilesCount = 0;
            m_generatedProjectiles.Clear();
            bool flag = false;
            int  num  = 0;

            while (num < m_queuedExplosions.Count)
            {
                ExplosionData explosionData = m_queuedExplosions[num];
                if (MathUtils.Abs(explosionData.X - x) <= 4 && MathUtils.Abs(explosionData.Y - y) <= 4 && MathUtils.Abs(explosionData.Z - z) <= 4)
                {
                    m_queuedExplosions.RemoveAt(num);
                    SimulateExplosion(explosionData.X, explosionData.Y, explosionData.Z, explosionData.Pressure, explosionData.IsIncendiary);
                    flag |= !explosionData.NoExplosionSound;
                }
                else
                {
                    num++;
                }
            }
            PostprocessExplosions(flag);
            if (!ShowExplosionPressure)
            {
                m_pressureByPoint            = null;
                m_surroundingPressureByPoint = null;
            }
        }
Beispiel #2
0
        public void TryAddPoint(int x, int y, int z, int axis, float currentPressure, bool isIncendiary, List <ProcessPoint> toProcess, SparseSpatialArray <bool> processed)
        {
            if (processed.Get(x, y, z))
            {
                return;
            }
            int cellValue = m_subsystemTerrain.Terrain.GetCellValue(x, y, z);
            int num       = Terrain.ExtractContents(cellValue);

            if (num != 0)
            {
                int   num2 = (int)(MathUtils.Hash((uint)(x + 913 * y + 217546 * z)) % 100u);
                float num3 = MathUtils.Lerp(1f, 2f, (float)num2 / 100f);
                if (num2 % 8 == 0)
                {
                    num3 *= 3f;
                }
                Block block = BlocksManager.Blocks[num];
                float num4  = m_pressureByPoint.Get(x - 1, y, z) + m_pressureByPoint.Get(x + 1, y, z) + m_pressureByPoint.Get(x, y - 1, z) + m_pressureByPoint.Get(x, y + 1, z) + m_pressureByPoint.Get(x, y, z - 1) + m_pressureByPoint.Get(x, y, z + 1);
                float num5  = MathUtils.Max(block.ExplosionResilience * num3, 1f);
                float num6  = num4 / num5;
                if (num6 > 1f)
                {
                    int newValue = Terrain.MakeBlockValue(0);
                    m_subsystemTerrain.DestroyCell(0, x, y, z, newValue, noDrop: true, noParticleSystem: true);
                    bool  flag        = false;
                    float probability = (num6 > 5f) ? 0.95f : 0.75f;
                    if (m_random.Bool(probability))
                    {
                        flag = TryExplodeBlock(x, y, z, cellValue);
                    }
                    if (!flag)
                    {
                        CalculateImpulseAndDamage(new Vector3((float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f), 60f, 2f * num4, out Vector3 impulse, out float _);
                        bool flag2 = false;
                        List <BlockDropValue> list = new List <BlockDropValue>();
                        block.GetDropValues(m_subsystemTerrain, cellValue, newValue, 0, list, out bool _);
                        if (list.Count == 0)
                        {
                            list.Add(new BlockDropValue
                            {
                                Value = cellValue,
                                Count = 1
                            });
                            flag2 = true;
                        }
                        foreach (BlockDropValue item in list)
                        {
                            int num7 = Terrain.ExtractContents(item.Value);
                            if (!(BlocksManager.Blocks[num7] is FluidBlock))
                            {
                                float num8 = (m_projectilesCount < 40) ? 1f : ((m_projectilesCount < 60) ? 0.5f : ((m_projectilesCount >= 80) ? 0.125f : 0.25f));
                                if (m_random.Float(0f, 1f) < num8)
                                {
                                    Vector3 velocity = impulse + m_random.Vector3(0.05f * impulse.Length());
                                    if (m_projectilesCount >= 1)
                                    {
                                        velocity *= m_random.Float(0.5f, 1f);
                                        velocity += m_random.Vector3(0.2f * velocity.Length());
                                    }
                                    float      num9       = flag2 ? 0f : MathUtils.Lerp(1f, 0f, (float)m_projectilesCount / 20f);
                                    Projectile projectile = m_subsystemProjectiles.AddProjectile(item.Value, new Vector3((float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f), velocity, m_random.Vector3(0f, 20f), null);
                                    projectile.ProjectileStoppedAction = ((!(m_random.Float(0f, 1f) < num9)) ? ProjectileStoppedAction.Disappear : ProjectileStoppedAction.TurnIntoPickable);
                                    if (m_random.Float(0f, 1f) < 0.5f && m_projectilesCount < 35)
                                    {
                                        float num10 = (num4 > 60f) ? m_random.Float(3f, 7f) : m_random.Float(1f, 3f);
                                        if (isIncendiary)
                                        {
                                            num10 += 10f;
                                        }
                                        m_subsystemProjectiles.AddTrail(projectile, Vector3.Zero, new SmokeTrailParticleSystem(15, m_random.Float(0.75f, 1.5f), num10, isIncendiary ? new Color(255, 140, 192) : Color.White));
                                        projectile.IsIncendiary = isIncendiary;
                                    }
                                    m_generatedProjectiles.Add(projectile, value: true);
                                    m_projectilesCount++;
                                }
                            }
                        }
                    }
                }
                else
                {
                    m_surroundingPressureByPoint.Set(x, y, z, new SurroundingPressurePoint
                    {
                        Pressure     = num4,
                        IsIncendiary = isIncendiary
                    });
                    if (block.IsCollidable)
                    {
                        return;
                    }
                }
            }
            toProcess.Add(new ProcessPoint
            {
                X    = x,
                Y    = y,
                Z    = z,
                Axis = axis
            });
            processed.Set(x, y, z, value: true);
        }
Beispiel #3
0
        public void SimulateExplosion(int x, int y, int z, float pressure, bool isIncendiary)
        {
            float num = MathUtils.Max(0.13f * MathUtils.Pow(pressure, 0.5f), 1f);

            m_subsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(0));
            SparseSpatialArray <bool> processed = new SparseSpatialArray <bool>(x, y, z, outside: true);
            List <ProcessPoint>       list      = new List <ProcessPoint>();
            List <ProcessPoint>       list2     = new List <ProcessPoint>();
            List <ProcessPoint>       list3     = new List <ProcessPoint>();

            TryAddPoint(x, y, z, -1, pressure, isIncendiary, list, processed);
            int num2 = 0;
            int num3 = 0;

            while (list.Count > 0 || list2.Count > 0)
            {
                num2 += list.Count;
                num3++;
                float num4 = 5f * (float)MathUtils.Max(num3 - 7, 0);
                float num5 = pressure / (MathUtils.Pow(num2, 0.66f) + num4);
                if (num5 >= num)
                {
                    foreach (ProcessPoint item in list)
                    {
                        float num6 = m_pressureByPoint.Get(item.X, item.Y, item.Z);
                        float num7 = num5 + num6;
                        m_pressureByPoint.Set(item.X, item.Y, item.Z, num7);
                        if (item.Axis == 0)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, -1, num7, isIncendiary, list2, processed);
                        }
                        else if (item.Axis == 1)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, -1, num7, isIncendiary, list2, processed);
                        }
                        else if (item.Axis == 2)
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, -1, num7, isIncendiary, list2, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, 2, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, 2, num7, isIncendiary, list3, processed);
                        }
                        else
                        {
                            TryAddPoint(item.X - 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X + 1, item.Y, item.Z, 0, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y - 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y + 1, item.Z, 1, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z - 1, 2, num7, isIncendiary, list3, processed);
                            TryAddPoint(item.X, item.Y, item.Z + 1, 2, num7, isIncendiary, list3, processed);
                        }
                    }
                }
                List <ProcessPoint> list4 = list;
                list4.Clear();
                list  = list2;
                list2 = list3;
                list3 = list4;
            }
        }