public void Update(float deltaTime)
        {
            // Solve constraints.
            if (m_simulator.Simulate(deltaTime))
            {
                m_SISimulated = true;
            }

            if (m_destructionDelayCounter > 0)
            {
                m_destructionDelayCounter--;
            }

            if (m_SISimulated && m_destructionDelayCounter == 0 && MyPetaInputComponent.ENABLE_SI_DESTRUCTIONS && !EnabledOnlyForDraw)
            { //supported weights changed
                if (Sync.IsServer)
                {
                    m_destructionDelayCounter = DestructionDelay;
                    m_SISimulated             = false;

                    MySlimBlock worstBlock = null;
                    float       maxTension = float.MinValue;

                    foreach (var block in m_cubeGrid.GetBlocks())
                    {
                        float tension = m_simulator.GetTension(block.Position);

                        if (tension > maxTension)
                        {
                            maxTension = tension;
                            worstBlock = block;
                        }
                    }

                    Vector3D worldCenter = Vector3D.Zero;
                    if (worstBlock != null)
                    {
                        worstBlock.ComputeWorldCenter(out worldCenter);
                    }

                    if (maxTension > MAX_SI_TENSION)
                    {
                        m_SISimulated = true;

                        CreateSIDestruction(worldCenter);
                    }
                }

                m_cubeGrid.TestDynamic = MyCubeGrid.MyTestDynamicReason.GridSplit;
            }
        }
Esempio n. 2
0
        public static void PlayDestructionSound(MySlimBlock b)
        {
            MyPhysicalMaterialDefinition def = null;

            if (b.FatBlock is MyCompoundCubeBlock)
            {
                var compound = b.FatBlock as MyCompoundCubeBlock;
                if (compound.GetBlocksCount() > 0)
                {
                    def = compound.GetBlocks()[0].BlockDefinition.PhysicalMaterial;
                }
            }
            else if (b.FatBlock is MyFracturedBlock)
            {
                MyCubeBlockDefinition bDef;
                if (MyDefinitionManager.Static.TryGetDefinition <MyCubeBlockDefinition>((b.FatBlock as MyFracturedBlock).OriginalBlocks[0], out bDef))
                {
                    def = bDef.PhysicalMaterial;
                }
            }
            else
            {
                def = b.BlockDefinition.PhysicalMaterial;
            }

            if (def == null)
            {
                return;
            }

            MySoundPair destructionCue;

            if (def.GeneralSounds.TryGetValue(m_destructionSound, out destructionCue) && !destructionCue.SoundId.IsNull)
            {
                var emmiter = MyAudioComponent.TryGetSoundEmitter();
                if (emmiter == null)
                {
                    return;
                }
                Vector3D pos;
                b.ComputeWorldCenter(out pos);
                emmiter.SetPosition(pos);
                emmiter.PlaySound(destructionCue);
            }
        }
        /// <summary>
        /// Performs a grid raycast (is prone to aliasing effects).
        /// It can be recursive (it calls CastPhysicsRay when exiting the grid or when it hits an empty cell).
        /// </summary>
        /// <param name="cubeBlock">Starting block</param>
        /// <returns>Returns starting damage for current stack</returns>
        private MyRaycastDamageInfo CastDDA(MySlimBlock cubeBlock)
        {
            if (m_damageRemaining.ContainsKey(cubeBlock))
            {
                return(m_damageRemaining[cubeBlock]);
            }

            stackOverflowGuard = 0;

            m_castBlocks.Push(cubeBlock);

            Vector3D startPosition;

            cubeBlock.ComputeWorldCenter(out startPosition);
            m_cells.Clear();
            cubeBlock.CubeGrid.RayCastCells(startPosition, m_explosion.Center, m_cells);
            var dir = (m_explosion.Center - startPosition);

            dir.Normalize();
            Vector3D oldCellWorldPosition = startPosition;

            foreach (var cell in m_cells)
            {
                Vector3D cellWorldPosition = Vector3D.Transform(cell * cubeBlock.CubeGrid.GridSize, cubeBlock.CubeGrid.WorldMatrix);
                if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_DDA_RAYCASTS)
                {
                    DrawRay(oldCellWorldPosition, cellWorldPosition, Color.Red, false);
                    oldCellWorldPosition = cellWorldPosition;
                }
                var cube = cubeBlock.CubeGrid.GetCubeBlock(cell);
                if (cube == null)
                {
                    if (IsExplosionInsideCell(cell, cubeBlock.CubeGrid))
                    {
                        return(new MyRaycastDamageInfo(m_explosionDamage, (float)(cellWorldPosition - m_explosion.Center).Length()));
                    }
                    else
                    {
                        //move to the edge of cube so we dont hit ourselves
                        //+ dir * (0.5 / dir).AbsMin()
                        //cmon cell is empty
                        return(CastPhysicsRay(cellWorldPosition));
                    }
                }
                if (cube != cubeBlock)
                {
                    if (m_damageRemaining.ContainsKey(cube))
                    {
                        return(m_damageRemaining[cube]);
                    }
                    else
                    {
                        if (!m_castBlocks.Contains(cube))
                        {
                            m_castBlocks.Push(cube);
                        }
                    }
                }
                else
                {
                    if (IsExplosionInsideCell(cell, cubeBlock.CubeGrid))
                    {
                        return(new MyRaycastDamageInfo(m_explosionDamage, (float)(cellWorldPosition - m_explosion.Center).Length()));
                    }
                }
            }

            return(new MyRaycastDamageInfo(m_explosionDamage, (float)(startPosition - m_explosion.Center).Length()));
        }
Esempio n. 4
0
        /// <summary>
        /// Performs a grid raycast (is prone to aliasing effects).
        /// It can be recursive (it calls CastPhysicsRay when exiting the grid or when it hits an empty cell).
        /// </summary>
        /// <param name="cubeBlock">Starting block</param>
        /// <returns>Returns starting damage for current stack</returns>
        private MyRaycastDamageInfo CastDDA(MySlimBlock cubeBlock)
        {
            if (m_damageRemaining.ContainsKey(cubeBlock))
            {
                return(m_damageRemaining[cubeBlock]);
            }

            stackOverflowGuard = 0;

            m_castBlocks.Push(cubeBlock);

            Vector3D startPosition;

            cubeBlock.ComputeWorldCenter(out startPosition);

            List <Vector3I> cells = new List <Vector3I>();

            cubeBlock.CubeGrid.RayCastCells(startPosition, m_explosion.Center, cells);
            Vector3D oldCellWorldPosition = startPosition;

            foreach (var cell in cells)
            {
                Vector3D cellWorldPosition = Vector3D.Transform(new Vector3(cell.X, cell.Y, cell.Z) * cubeBlock.CubeGrid.GridSize, cubeBlock.CubeGrid.WorldMatrix);
                if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_DDA_RAYCASTS)
                {
                    DrawRay(oldCellWorldPosition, cellWorldPosition, Color.Red, false);
                    oldCellWorldPosition = cellWorldPosition;
                }
                var cube = cubeBlock.CubeGrid.GetCubeBlock(cell);
                if (cube == null)
                {
                    if (IsExplosionInsideCell(cell, cubeBlock.CubeGrid))
                    {
                        return(new MyRaycastDamageInfo(m_explosionDamage, (float)(cellWorldPosition - m_explosion.Center).Length()));
                    }
                    else
                    {
                        return(CastPhysicsRay(cellWorldPosition));
                    }
                }
                if (cube != cubeBlock)
                {
                    if (m_damageRemaining.ContainsKey(cube))
                    {
                        return(m_damageRemaining[cube]);
                    }
                    else
                    {
                        if (!m_castBlocks.Contains(cube))
                        {
                            m_castBlocks.Push(cube);
                        }
                    }
                }
                else
                {
                    if (IsExplosionInsideCell(cell, cubeBlock.CubeGrid))
                    {
                        return(new MyRaycastDamageInfo(m_explosionDamage, (float)(cellWorldPosition - m_explosion.Center).Length()));
                    }
                }
            }

            return(new MyRaycastDamageInfo(m_explosionDamage, (float)(startPosition - m_explosion.Center).Length()));
        }