// Add new explosion to the list, but caller needs to start it using Start() method public static void AddExplosion(ref MyExplosionInfo explosionInfo, bool updateSync = true) { System.Diagnostics.Debug.Assert(explosionInfo.ExplosionSphere.Radius > 0); if (updateSync) { SyncObject.RequestExplosion( explosionInfo.ExplosionSphere.Center, (float)explosionInfo.ExplosionSphere.Radius, explosionInfo.ExplosionType, explosionInfo.VoxelExplosionCenter, explosionInfo.ParticleScale ); } m_explosionsWrite.Add(explosionInfo); }
// Add new explosion to the list, but caller needs to start it using Start() method public static void AddExplosion(ref MyExplosionInfo explosionInfo, bool updateSync = true) { System.Diagnostics.Debug.Assert(explosionInfo.ExplosionSphere.Radius > 0); if (updateSync) { MyMultiplayer.RaiseStaticEvent(s => MyExplosions.ProxyExplosionRequest, explosionInfo.ExplosionSphere.Center, (float)explosionInfo.ExplosionSphere.Radius, explosionInfo.ExplosionType, explosionInfo.VoxelExplosionCenter, explosionInfo.ParticleScale ); } m_explosionsWrite.Add(explosionInfo); }
private static void ProxyExplosionRequest(Vector3D center, float radius, MyExplosionTypeEnum type, Vector3D voxelCenter, float particleScale) { //Dont create explosion particles if message is bufferred, it is useless to create hundred explosion after scene load if (MySession.Static.Ready) { // Create explosion MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, //Damage = m_ammoProperties.Damage, Damage = 200, ExplosionType = type, ExplosionSphere = new BoundingSphere(center, radius), LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = null, ParticleScale = particleScale, OwnerEntity = null, Direction = Vector3.Forward, VoxelExplosionCenter = voxelCenter, ExplosionFlags = MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS, VoxelCutoutScale = 1.0f, PlaySound = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info, false); } }
public override void Update() { base.Update(); if (m_selfDestruct && MySandboxGame.TotalGamePlayTimeInMilliseconds >= m_selfDestructStartedInTime + SELF_DESTRUCT_TIME_MS) { MyAIComponent.Static.RemoveBot(AgentBot.Player.Id.SerialId, removeCharacter: true); var explosionSphere = new BoundingSphere(AgentBot.Player.GetPosition(), EXPLOSION_RADIUS); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = EXPLOSION_PLAYER_DAMAGE, Damage = EXPLOSION_DAMAGE, ExplosionType = MyExplosionTypeEnum.BOMB_EXPLOSION, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = AgentBot.Player.Character, ParticleScale = 0.5f, OwnerEntity = AgentBot.Player.Character, Direction = Vector3.Zero, VoxelExplosionCenter = AgentBot.Player.Character.PositionComp.GetPosition(),// + 2 * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.6f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } var target = (AiTarget as MyCyberhoundTarget); Debug.Assert(target != null); if (AgentBot.Player.Character.UseNewAnimationSystem == false) // obsolete in new animation system { if ((!target.IsAttacking && !m_lastWasAttacking) && target.HasTarget() && !target.PositionIsNearTarget(AgentBot.Player.Character.PositionComp.GetPosition(), 1.5f)) { if (AgentBot.Navigation.Stuck) { // correct aiming (aim in front of dog) Vector3D houndPosition = AgentBot.Player.Character.PositionComp.GetPosition(); Vector3D gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(houndPosition); Vector3D aimingDirection = AgentBot.Player.Character.AimedPoint - houndPosition; Vector3D newAimVector = aimingDirection - gravity*Vector3D.Dot(aimingDirection, gravity)/gravity.LengthSquared(); newAimVector.Normalize(); AgentBot.Navigation.AimAt(null, houndPosition + 100.0f*newAimVector); // play idle animation AgentBot.Player.Character.PlayCharacterAnimation("CyberhoundIdle1", MyBlendOption.Immediate, MyFrameOption.Loop, 0); AgentBot.Player.Character.DisableAnimationCommands(); } else { AgentBot.Player.Character.EnableAnimationCommands(); } } } m_lastWasAttacking = target.IsAttacking; }
public static void CreateExplosion(Vector3D position, float radius, int damage = 5000) { var explosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_50; if (radius < 2) explosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_02; else if (radius < 15) explosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15; else if (radius < 30) explosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_30; // Create explosion MyExplosionInfo info = new MyExplosionInfo { PlayerDamage = 0, Damage = damage, ExplosionType = explosionType, ExplosionSphere = new BoundingSphereD(position, radius), LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, ParticleScale = 1, Direction = Vector3.Down, VoxelExplosionCenter = position, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 1.0f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); }
MyDamageInfo ApplyVolumetricExplosionOnGrid(ref MyExplosionInfo explosionInfo, ref BoundingSphereD sphere, List<MyEntity> entities) { Debug.Assert(Sandbox.Game.Multiplayer.Sync.IsServer, "This is supposed to be only server method"); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionOnGrid"); bool gridWasHit = false; HashSet<MySlimBlock> explodedBlocks = new HashSet<MySlimBlock>(); Dictionary<MySlimBlock, float> damagedBlocks = new Dictionary<MySlimBlock, float>(); HashSet<MyCubeGrid> explodedGrids = new HashSet<MyCubeGrid>(); foreach (var entity in entities) { MyCubeGrid grid = entity as MyCubeGrid; if (grid != null && grid.CreatePhysics) { explodedGrids.Add(grid); var detectionHalfSize = grid.GridSize / 2 / 1.25f; var invWorldGrid = MatrixD.Invert(grid.WorldMatrix); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("GetBlocksInsideSpheres"); BoundingSphereD innerSphere = new BoundingSphereD(sphere.Center, (float)Math.Max(0.1f, sphere.Radius - grid.GridSize)); BoundingSphereD exactSphere = new BoundingSphereD(sphere.Center, sphere.Radius); BoundingSphereD outerSphere = new BoundingSphereD(sphere.Center, sphere.Radius + grid.GridSize * 0.5f * (float)Math.Sqrt(3)); grid.GetBlocksInsideSpheres( ref innerSphere, ref exactSphere, ref outerSphere, m_explodedBlocksInner, m_explodedBlocksExact, m_explodedBlocksOuter, false, detectionHalfSize, ref invWorldGrid); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); m_explodedBlocksInner.UnionWith(m_explodedBlocksExact); explodedBlocks.UnionWith(m_explodedBlocksInner); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("outerSphere2"); foreach (var cubeBlock in m_explodedBlocksOuter) { grid.Physics.AddDirtyBlock(cubeBlock); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); m_explodedBlocksInner.Clear(); m_explodedBlocksExact.Clear(); m_explodedBlocksOuter.Clear(); gridWasHit = true; } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); var damage = new MyExplosionDamage(explodedBlocks, sphere, explosionInfo.Damage); var damageInfo = new MyDamageInfo { GridWasHit = gridWasHit, ExplosionDamage = damage, AffectedCubeBlocks = explodedBlocks, AffectedCubeGrids = explodedGrids, Sphere = sphere }; return damageInfo; }
void ApplyExplosionOnVoxel(ref MyExplosionInfo explosionInfo) { if (MySession.Static.EnableVoxelDestruction == false) { return; } VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionOnVoxel"); if (explosionInfo.Damage > 0) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Voxel or collision"); bool first = true; // If explosion sphere intersects a voxel map, we need to cut out a sphere, spawn debrises, etc List<MyVoxelBase> voxelMaps = MySession.Static.VoxelMaps.GetAllOverlappingWithSphere(ref m_explosionSphere); voxelMaps.Sort(delegate(MyVoxelBase x, MyVoxelBase y) { return y.GetOrePriority() - x.GetOrePriority(); }); foreach(var voxelMap in voxelMaps) { // If the voxel is to be ignored. if (voxelMap.GetOrePriority() == MyVoxelConstants.PRIORITY_IGNORE_EXTRACTION) continue; bool createDebris = first; // We want to create debris if (explosionInfo.HitEntity != null) // but not when we hit prefab { createDebris &= explosionInfo.HitEntity is MyVoxelBase; } createDebris &= explosionInfo.CreateDebris && (createDebris || explosionInfo.ForceDebris); CutOutVoxelMap((float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, explosionInfo.VoxelExplosionCenter, voxelMap, createDebris); //Sync voxelMap.RequestVoxelCutoutSphere(explosionInfo.VoxelExplosionCenter, (float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, createDebris, false); first = false; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
// Doesn't get called anymore? bool ApplyExplosionOnGrid(ref MyExplosionInfo explosionInfo, ref BoundingSphereD sphere, List<MyEntity> entities) { Debug.Assert(Sandbox.Game.Multiplayer.Sync.IsServer, "This is supposed to be only server method"); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionOnGrid"); bool gridWasHit = false; foreach (var entity in entities) { MyCubeGrid grid = entity as MyCubeGrid; if (grid != null && grid.BlocksDestructionEnabled) { var detectionHalfSize = grid.GridSize / 2 / 1.25f; var invWorldGrid = MatrixD.Invert(grid.WorldMatrix); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("GetBlocksInsideSpheres"); BoundingSphereD innerSphere = new BoundingSphereD(sphere.Center, (float)Math.Max(0.1f, sphere.Radius - grid.GridSize)); BoundingSphereD exactSphere = new BoundingSphereD(sphere.Center, sphere.Radius); BoundingSphereD outerSphere = new BoundingSphereD(sphere.Center, sphere.Radius + grid.GridSize * 0.5f * (float)Math.Sqrt(3)); grid.GetBlocksInsideSpheres( ref innerSphere, ref exactSphere, ref outerSphere, m_explodedBlocksInner, m_explodedBlocksExact, m_explodedBlocksOuter, true, detectionHalfSize, ref invWorldGrid); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("foreach (var cubeBlock in m_explodedBlocks)"); foreach (var cubeBlock in m_explodedBlocksInner) { if (cubeBlock.FatBlock != null && cubeBlock.FatBlock.MarkedForClose) continue; if (cubeBlock.FatBlock != null) { grid.RemoveBlock(cubeBlock, updatePhysics: true); } else { grid.RemoveDestroyedBlock(cubeBlock); grid.Physics.AddDirtyBlock(cubeBlock); } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("GetBlocksInsideSphere outerSphere"); foreach (var cubeBlock in m_explodedBlocksExact) { if ((cubeBlock.FatBlock != null) && cubeBlock.FatBlock.MarkedForClose) continue; if ((cubeBlock.FatBlock != null) && cubeBlock.FatBlock.MarkedToExplode) { grid.RemoveBlock(cubeBlock, updatePhysics: true); } else// if (MyVRageUtils.GetRandomFloat(0, 2) > 1) { grid.ApplyDestructionDeformation(cubeBlock); grid.Physics.AddDirtyBlock(cubeBlock); } //else if (cubeBlock.FatBlock is IMyExplosiveObject) //{ // cubeBlock.OnDestroy(); //} } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("outerSphere2"); foreach (var cubeBlock in m_explodedBlocksOuter) { grid.Physics.AddDirtyBlock(cubeBlock); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); m_explodedBlocksInner.Clear(); m_explodedBlocksExact.Clear(); m_explodedBlocksOuter.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("AddDirtyArea"); //Vector3 cornerVec = new Vector3(sphere.Radius + grid.GridSize / (float)grid.Skeleton.BoneDensity); //BoundingBox box = new BoundingBox(sphere.Center - cornerVec, sphere.Center + cornerVec); //var invee = Matrix.Invert(grid.WorldMatrix); //box = box.Transform(ref invee); //Vector3 min = box.Min; //Vector3 max = box.Max; //Vector3I start = new Vector3I((int)Math.Round(min.X / grid.GridSize), (int)Math.Round(min.Y / grid.GridSize), (int)Math.Round(min.Z / grid.GridSize)); //Vector3I end = new Vector3I((int)Math.Round(max.X / grid.GridSize), (int)Math.Round(max.Y / grid.GridSize), (int)Math.Round(max.Z / grid.GridSize)); //grid.Physics.AddDirtyArea(start, end); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("UpdateDirty"); grid.UpdateDirty(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("CreateExplosionDebris"); if (m_explosionInfo.HitEntity == grid) { BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(sphere.Center, sphere.Radius * 1.5f)); MyDebris.Static.CreateExplosionDebris(ref sphere, grid, ref aabb, 0.5f, false); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); gridWasHit = true; } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return gridWasHit; }
// Doesn't get called anymore? private void ApplyExplosionOnEntities(ref MyExplosionInfo m_explosionInfo,List<MyEntity> entities) { Debug.Assert(Sync.IsServer); foreach (var entity in entities) { if (!(entity is IMyDestroyableObject)) continue; float damage; if (entity is MyCharacter) damage = m_explosionInfo.PlayerDamage; else damage = m_explosionInfo.Damage; if (damage == 0) continue; var destroyableObj = entity as IMyDestroyableObject; destroyableObj.DoDamage(damage, MyDamageType.Explosion, true, attackerId: m_explosionInfo.OwnerEntity != null ? m_explosionInfo.OwnerEntity.EntityId : 0); } }
private void ApplyVolumetricExplosionOnEntities(ref MyExplosionInfo m_explosionInfo, List<MyEntity> entities, MyDamageInfo explosionDamageInfo) { Debug.Assert(Sync.IsServer); foreach (var entity in entities) { //Special case for characters in cockpits var character = entity as MyCharacter; if (character != null) { var cockpit = character.IsUsing as MyCockpit; if (cockpit != null) { if (explosionDamageInfo.ExplosionDamage.DamagedBlocks.ContainsKey(cockpit.SlimBlock)) { float damageRemaining = explosionDamageInfo.ExplosionDamage.DamageRemaining[cockpit.SlimBlock].DamageRemaining; character.DoDamage(damageRemaining, MyDamageType.Explosion, true, attackerId: m_explosionInfo.OwnerEntity != null ? m_explosionInfo.OwnerEntity.EntityId : 0); } continue; } } var raycastDamageInfo = explosionDamageInfo.ExplosionDamage.ComputeDamageForEntity(entity.PositionComp.WorldAABB.Center); float damage = raycastDamageInfo.DamageRemaining; float entityDistanceToExplosion = (float)(entity.PositionComp.WorldAABB.Center - explosionDamageInfo.Sphere.Center).Length(); damage *= (float)(1 - (entityDistanceToExplosion - raycastDamageInfo.DistanceToExplosion) / (explosionDamageInfo.Sphere.Radius - raycastDamageInfo.DistanceToExplosion)); if (damage <= 0f) continue; if (entity.Physics != null && entity.Physics.Enabled) { var ammoBase = entity as MyAmmoBase; if (ammoBase != null) { if (Vector3.DistanceSquared(m_explosionSphere.Center, ammoBase.PositionComp.GetPosition()) < 4 * m_explosionSphere.Radius * m_explosionSphere.Radius) { ammoBase.MarkedToDestroy = true; } ammoBase.Explode(); } float forceMultiplier = damage / 50000f; // Throws surrounding objects away from centre of the explosion. if (m_explosionInfo.ApplyForceAndDamage) { m_explosionInfo.StrengthImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE * (float)m_explosionSphere.Radius; m_explosionInfo.StrengthAngularImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_ANGULAR_IMPULSE; m_explosionInfo.HitEntity = m_explosionInfo.HitEntity != null ? m_explosionInfo.HitEntity.GetBaseEntity() : null; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionForceAndDamage"); if (entity.PositionComp.WorldAABB.Center != m_explosionSphere.Center) { entity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, forceMultiplier * m_explosionInfo.StrengthImpulse * Vector3.Normalize(entity.PositionComp.WorldAABB.Center - m_explosionSphere.Center), entity.PositionComp.WorldAABB.Center, null); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } } if (!(entity is IMyDestroyableObject)) continue; var destroyableObj = entity as IMyDestroyableObject; destroyableObj.DoDamage(damage, MyDamageType.Explosion, true, attackerId: m_explosionInfo.OwnerEntity != null ? m_explosionInfo.OwnerEntity.EntityId : 0); } }
private bool ApplyVolumetricExplosion(ref MyExplosionInfo m_explosionInfo, ref BoundingSphereD influenceExplosionSphere, List<MyEntity> entities) { bool gridWasHit = false; ApplyExplosionOnVoxel(ref m_explosionInfo); var damageInfo = ApplyVolumetricExplosionOnGrid(ref m_explosionInfo, ref influenceExplosionSphere, entities); if ((m_explosionInfo.ExplosionFlags & MyExplosionFlags.APPLY_DEFORMATION) == MyExplosionFlags.APPLY_DEFORMATION) { damageInfo.ExplosionDamage.ComputeDamagedBlocks(); gridWasHit = damageInfo.GridWasHit; ApplyVolumetriDamageToGrid(damageInfo, m_explosionInfo.OwnerEntity != null ? m_explosionInfo.OwnerEntity.EntityId : 0); } if (m_explosionInfo.HitEntity is MyWarhead) { var warhead = (m_explosionInfo.HitEntity as MyWarhead).SlimBlock; if (!warhead.CubeGrid.BlocksDestructionEnabled) { warhead.CubeGrid.RemoveDestroyedBlock(warhead); foreach (var neighbour in warhead.Neighbours) { neighbour.CubeGrid.Physics.AddDirtyBlock(neighbour); } warhead.CubeGrid.Physics.AddDirtyBlock(warhead); } } ApplyVolumetricExplosionOnEntities(ref m_explosionInfo, entities, damageInfo); entities.Clear(); return gridWasHit; }
// Doesn't get called anymore? private bool ApplyExplosion(ref MyExplosionInfo m_explosionInfo, ref BoundingSphereD influenceExplosionSphere, List<MyEntity> entities) { bool gridWasHit = false; ApplyExplosionOnVoxel(ref m_explosionInfo); ApplyExplosionOnEntities(ref m_explosionInfo, entities); if (((m_explosionInfo.ExplosionFlags & MyExplosionFlags.APPLY_DEFORMATION) == MyExplosionFlags.APPLY_DEFORMATION)) { gridWasHit = ApplyExplosionOnGrid(ref m_explosionInfo, ref influenceExplosionSphere, entities); } entities.Clear(); // Throws surrounding objects away from centre of the explosion. if (m_explosionInfo.ApplyForceAndDamage) { m_explosionInfo.StrengthImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE * (float)m_explosionSphere.Radius; m_explosionInfo.StrengthAngularImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_ANGULAR_IMPULSE; m_explosionInfo.HitEntity = m_explosionInfo.HitEntity != null ? m_explosionInfo.HitEntity.GetBaseEntity() : null; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionForceAndDamage"); //MyEntities.ApplyExplosionForceAndDamage(ref explosionInfo); for (int s = 0; s < m_explosionForceSlices.Length; s++) { BoundingSphereD forceImpactSphere = m_explosionSphere; forceImpactSphere.Radius *= m_explosionForceSlices[s].X; entities = MyEntities.GetEntitiesInSphere(ref forceImpactSphere); foreach (var entity in entities) { if (!m_pushedEntities.Contains(entity)) { if (entity.PositionComp.WorldAABB.Center != m_explosionSphere.Center) { if (entity.Physics != null && entity.Physics.Enabled) { entity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, m_explosionForceSlices[s].Y * m_explosionInfo.StrengthImpulse * Vector3.Normalize(entity.PositionComp.WorldAABB.Center - m_explosionSphere.Center), entity.PositionComp.WorldAABB.Center, null); } } m_pushedEntities.Add(entity); if (entity.Physics != null && entity.Physics.Enabled) { var character = entity as Sandbox.Game.Entities.Character.MyCharacter; if (character != null && !(character.IsUsing is MyCockpit)) { character.DoDamage(m_explosionInfo.Damage * m_explosionForceSlices[s].Y, MyDamageType.Explosion, true, m_explosionInfo.OwnerEntity != null ? m_explosionInfo.OwnerEntity.EntityId : 0); } var ammoBase = entity as MyAmmoBase; if (ammoBase != null) { if (Vector3.DistanceSquared(m_explosionSphere.Center, ammoBase.PositionComp.GetPosition()) < 4 * m_explosionSphere.Radius * m_explosionSphere.Radius) { ammoBase.MarkedToDestroy = true; } ammoBase.Explode(); } } } } entities.Clear(); } m_pushedEntities.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } return gridWasHit; }
public void Start(MyExplosionInfo explosionInfo) { MyDebug.AssertDebug(explosionInfo.ExplosionSphere.Radius > 0); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyExplosion.Start"); m_explosionInfo = explosionInfo; ElapsedMiliseconds = 0; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
void ApplyExplosionOnVoxel(ref MyExplosionInfo explosionInfo) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionOnVoxel"); if (explosionInfo.Damage > 0) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Voxel or collision"); // If explosion sphere intersects a voxel map, we need to cut out a sphere, spawn debrises, etc MyVoxelBase voxelMap = explosionInfo.AffectVoxels ? MySession.Static.VoxelMaps.GetOverlappingWithSphere(ref m_explosionSphere) : null; if (voxelMap != null) { bool createDebris = true; // We want to create debris if (explosionInfo.HitEntity != null) // but not when we hit prefab { createDebris &= explosionInfo.HitEntity is MyVoxelMap; } createDebris &= explosionInfo.CreateDebris && (createDebris || explosionInfo.ForceDebris); CutOutVoxelMap((float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, explosionInfo.VoxelExplosionCenter, voxelMap, createDebris); //Sync voxelMap.SyncObject.RequestVoxelCutoutSphere(explosionInfo.VoxelExplosionCenter, (float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, createDebris); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
void ApplyExplosionOnVoxel(ref MyExplosionInfo explosionInfo) { if (MySession.Static.EnableVoxelDestruction == false) { return; } VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyExplosionOnVoxel"); if (explosionInfo.Damage > 0) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Voxel or collision"); bool first = true; // If explosion sphere intersects a voxel map, we need to cut out a sphere, spawn debrises, etc List<MyVoxelBase> voxelMaps = MySession.Static.VoxelMaps.GetAllOverlappingWithSphere(ref m_explosionSphere); for (int i = voxelMaps.Count - 1; i > 0; --i) { m_VoxelsToCutTmp.Add(voxelMaps[i].RootVoxel); } foreach (var voxelMap in m_VoxelsToCutTmp) { bool createDebris = first; // We want to create debris /* if (explosionInfo.HitEntity != null) // but not when we hit prefab { createDebris &= explosionInfo.HitEntity is MyVoxelBase; }*/ createDebris &= explosionInfo.CreateDebris && (createDebris || explosionInfo.ForceDebris); CutOutVoxelMap((float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, explosionInfo.VoxelExplosionCenter, voxelMap, createDebris); //Sync voxelMap.RequestVoxelCutoutSphere(explosionInfo.VoxelExplosionCenter, (float)m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale, createDebris, false); first = false; } m_VoxelsToCutTmp.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }