示例#1
0
        private Vector3D PlaceDecal()
        {
            Vector3D  explosionPoint = m_collisionPoint.Value;
            MyHitInfo hitInfo        = new MyHitInfo()
            {
                Position = explosionPoint, Normal = m_collisionNormal
            };

            MyDecals.HandleAddDecal(m_collidedEntity, hitInfo, this.m_missileAmmoDefinition.PhysicalMaterial);
            return(explosionPoint);
        }
示例#2
0
        private void RemoveDecal(Vector3I position, ConcurrentQueue <MyDecalPartIdentity> decals, MyCube cube)
        {
            MyDecalPartIdentity identity;

            decals.TryDequeue(out identity);
            MyDecals.RemoveDecal(identity.DecalId);
            if (identity.CubePartIndex != -1)
            {
                MyCubePart part = cube.Parts[identity.CubePartIndex];
                this.GetOrAddCell((Vector3)position, true).RemoveCubePartDecal(part, identity.DecalId);
            }
        }
示例#3
0
        protected void CutOutFromVoxel(MyVoxelMap voxelMap, ref BoundingSphere bigSphereForTunnel)
        {
            if (!IsDummy)
            {
                if (MyMultiplayerGameplay.IsRunning)
                {
                    MyMultiplayerGameplay.Static.CutOut(voxelMap, ref bigSphereForTunnel);
                }

                //remove decals
                MyDecals.HideTrianglesAfterExplosion(voxelMap, ref bigSphereForTunnel);

                //cut off
                MyVoxelGenerator.CutOutSphereFast(voxelMap, bigSphereForTunnel);


                if (MySession.Is25DSector)
                {
                    //  Create debris rocks thrown from the explosion
                    MyExplosionDebrisVoxel.CreateExplosionDebris(ref bigSphereForTunnel, 1, CommonLIB.AppCode.Networking.MyMwcVoxelMaterialsEnum.Ice_01, MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip.GroupMask, voxelMap);

                    BoundingBox boundingBox = BoundingBoxHelper.InitialBox;
                    BoundingBoxHelper.AddSphere(ref bigSphereForTunnel, ref boundingBox);

                    // we need local list because this method can be called from inside of the loop

                    var elements = MyEntities.GetElementsInBox(ref boundingBox);
                    foreach (var el in elements)
                    {
                        MyEntity entity = ((MinerWars.AppCode.Game.Physics.MyPhysicsBody)el.GetRigidBody().m_UserData).Entity;
                        MyExplosionDebrisVoxel debris = entity as MyExplosionDebrisVoxel;

                        if (debris == null)
                        {
                            continue;
                        }

                        Vector3 awayDirection = debris.GetPosition() - bigSphereForTunnel.Center;

                        debris.Physics.AddForce(
                            MinerWars.AppCode.Game.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            awayDirection * MyExplosionsConstants.EXPLOSION_FORCE_RADIUS_MULTIPLIER * 100000,
                            bigSphereForTunnel.Center,
                            MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomVector3Normalized() * 10000);
                    }

                    elements.Clear();
                }

                PlayVoxelCutCue();
            }
        }
        void OnCutOut(ref MyEventCutOut msg)
        {
            MyVoxelMap voxelMap;

            if (MyEntities.TryGetEntityById <MyVoxelMap>(msg.VoxelMapEntityId.ToEntityId(), out voxelMap))
            {
                var sphere = new BoundingSphere(msg.Position, msg.Radius);

                //remove decals
                MyDecals.HideTrianglesAfterExplosion(voxelMap, ref sphere);

                //cut off
                MyVoxelGenerator.CutOutSphereFast(voxelMap, sphere);
            }
        }
        /// <param name="position">Position of the decal in the binding pose</param>
        protected void AddBoneDecal(uint decalId, int boneIndex)
        {
            List <uint> decals;
            bool        found = m_boneDecals.TryGetValue(boneIndex, out decals);

            if (!found)
            {
                decals = new List <uint>(MAX_BONE_DECALS_COUNT);
                m_boneDecals.Add(boneIndex, decals);
            }

            if (decals.Count == decals.Capacity)
            {
                MyDecals.RemoveDecal(decals[0]);
                decals.RemoveAt(0);
            }

            decals.Add(decalId);
        }
示例#6
0
        public void AddDecal(Vector3I cube, uint decalId)
        {
            List <uint> decals;
            bool        found = m_cubeDecals.TryGetValue(cube, out decals);

            if (!found)
            {
                decals             = new List <uint>();
                m_cubeDecals[cube] = decals;
            }

            if (decals.Count > MAX_DECALS_PER_CUBE)
            {
                MyDecals.RemoveDecal(decals[0]);
                decals.RemoveAt(0);
            }

            decals.Add(decalId);
        }
示例#7
0
        /// <param name="position">Position of the decal in the binding pose</param>
        protected void AddBoneDecal(uint decalId, Vector3 hitPosition, Vector3 hitNormal, int boneIndex)
        {
            List <MyDecalHitInfo> decals;
            bool found = m_boneDecals.TryGetValue(boneIndex, out decals);

            if (!found)
            {
                decals = new List <MyDecalHitInfo>(MAX_BONE_DECALS_COUNT);
                m_boneDecals.Add(boneIndex, decals);
            }

            if (decals.Count == decals.Capacity)
            {
                MyDecals.RemoveDecal(decals[0].ID);
                decals.RemoveAt(0);
            }

            decals.Add(new MyDecalHitInfo()
            {
                ID = decalId, Position = hitPosition, Normal = hitNormal
            });
        }
示例#8
0
        private void RemoveDecal(Vector3I position, List <MyDecalPartIdentity> decals, int index, ref MyCube cube)
        {
            MyDecalPartIdentity decal = decals[index];

            MyDecals.RemoveDecal(decal.DecalId);

            if (cube == null)
            {
                bool found = m_gridRender.CubeGrid.TryGetCube(position, out cube);
                if (!found)
                {
                    return;
                }
            }

            if (decal.CubePartIndex != -1)
            {
                var part = cube.Parts[decal.CubePartIndex];
                var cell = GetCell(position);
                cell.RemoveCubePartDecal(part, decal.DecalId);
            }
        }
示例#9
0
        private void UpdateDecalPositions()
        {
            m_decalUpdateCache.Clear();
            foreach (var pair in m_boneDecals)
            {
                int             boneIndex = pair.Key;
                MyCharacterBone bone      = AnimationController.CharacterBones[boneIndex];
                bone.ComputeAbsoluteTransform();
                Matrix boneTrans = bone.SkinTransform * bone.AbsoluteTransform;;
                for (int it = 0; it < pair.Value.Count; it++)
                {
                    MyDecalHitInfo decal         = pair.Value[it];
                    Vector3        positionTrans = Vector3.Transform(decal.Position, ref boneTrans);
                    Vector3        normalTrans   = Vector3.TransformNormal(decal.Normal, boneTrans);
                    m_decalUpdateCache.Add(new MyDecalPositionUpdate()
                    {
                        ID = decal.ID, Position = positionTrans, Normal = normalTrans
                    });
                }
            }

            MyDecals.UpdateDecals(m_decalUpdateCache);
        }
示例#10
0
        private void CreateDecals(Vector3 direction)
        {
            MyRender.GetRenderProfiler().StartProfilingBlock("Collisions");

            MyRender.GetRenderProfiler().StartProfilingBlock("Raycast");

            var intersectionEndPoint   = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction;
            var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction;
            var line = new MyLine(intersectionStartPoint, intersectionEndPoint);

            var result = MyEntities.GetIntersectionWithLine(ref line, null, null, true, true, false, false, true, AppCode.Physics.Collisions.IntersectionFlags.ALL_TRIANGLES, true);

            MyRender.GetRenderProfiler().EndProfilingBlock();
            MyRender.GetRenderProfiler().StartProfilingBlock("Add decal");

            if (result.HasValue)
            {
                MyIntersectionResultLineTriangleEx intersection = result.Value;

                var radius = m_explosionSphere.Radius * (result.Value.Entity is MyVoxelMap ? 1.0f : MyMwcUtils.GetRandomFloat(0.4f, 0.6f));

                MyDecals.Add(
                    MyDecalTexturesEnum.ExplosionSmut,
                    radius,
                    MyMwcUtils.GetRandomRadian(),
                    GetSmutDecalRandomColor(),
                    true,
                    ref intersection,
                    0,
                    0,
                    MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS);
            }

            MyRender.GetRenderProfiler().EndProfilingBlock();
            MyRender.GetRenderProfiler().EndProfilingBlock();

            //var elements = MyEntities.GetElementsInBox(ref boundingBox);

            //foreach (MyRBElement element in elements)
            //{
            //    var rigidBody = (MyPhysicsBody)element.GetRigidBody().m_UserData;
            //    var entity = rigidBody.Entity;

            //    if (entity is MyExplosionDebrisBase || entity is MyPrefabContainer)
            //        continue;

            //    // Making interesection of line from the explosion center to every object closed to explosion
            //    // and placing smut decals

            //    // FIX : when hitting another samll boat explosion and entity position are equal !!!
            //    //if (m_explosionSphere.Center == entity.GetPosition())
            //    //    continue;

            //    // FIX : when hitting another samll boat explosion and direction is < Epsilon !!!
            //    if ((entity.GetPosition() - m_explosionSphere.Center).LengthSquared() <
            //        2 * MyMwcMathConstants.EPSILON_SQUARED)
            //        continue;

            //    MyRender.GetRenderProfiler().StartProfilingBlock("Line intersection");
            //    MyIntersectionResultLineTriangleEx? intersection = null;
            //    if (direction.HasValue)
            //    {
            //        var intersectionEndPoint = m_explosionSphere.Center + 1.5f * m_explosionSphere.Radius * direction.Value;
            //        var intersectionStartPoint = m_explosionSphere.Center - 1.5f * m_explosionSphere.Radius * direction.Value;
            //        MyLine intersectionLine = new MyLine(intersectionStartPoint, intersectionEndPoint, true);
            //        entity.GetIntersectionWithLine(ref intersectionLine, out intersection);
            //    }
            //    else if (intersection == null && entity is MyVoxelMap)
            //    {
            //        // fall back if we dont have direction
            //        var intersectionEndPoint = entity.GetPosition();
            //        MyLine intersectionLine = new MyLine(m_explosionSphere.Center, intersectionEndPoint, true);
            //        entity.GetIntersectionWithLine(ref intersectionLine, out intersection);
            //    }
            //    MyRender.GetRenderProfiler().EndProfilingBlock();

            //    if (intersection == null)
            //        continue;

            //    MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value;

            //    if (entity is MyVoxelMap)
            //    {
            //        MyRender.GetRenderProfiler().StartProfilingBlock("Decals");

            //        MyDecals.Add(
            //            MyDecalTexturesEnum.ExplosionSmut,
            //            m_explosionSphere.Radius,
            //            MyMwcUtils.GetRandomRadian(),
            //            GetSmutDecalRandomColor(),
            //            true,
            //            ref intersectionValue,
            //            0,
            //            0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL_FOR_SMUT_DECALS);

            //        MyRender.GetRenderProfiler().EndProfilingBlock();
            //    }
            //    else if (((entity is MySmallShip) == false) &&
            //             ((entity is MySmallDebris) == false)
            //             && ((entity is MyAmmoBase) == false))
            //    {
            //        //  Create explosion smut decal on model we hit by this missile
            //        MyDecals.Add(
            //            MyDecalTexturesEnum.ExplosionSmut,
            //            MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.4f, m_explosionSphere.Radius * 0.6f),
            //            MyMwcUtils.GetRandomRadian(),
            //            GetSmutDecalRandomColor(),
            //            true,
            //            ref intersectionValue,
            //            0,
            //            0, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL);
            //    }
            //}
            //elements.Clear();
        }
示例#11
0
        /// <summary>
        /// Starts the explosion.
        /// </summary>
        /// <param name="damage"></param>
        /// <param name="type"></param>
        /// <param name="explosionSphere"></param>
        /// <param name="lifespanInMiliseconds"></param>
        /// <param name="explosionForceDirection"></param>
        /// <param name="groupMask"></param>
        /// <param name="createExplosionDebris"></param>
        /// <param name="cascadeLevel"></param>
        /// <param name="hitEntity"></param>
        /// <param name="particleScale"></param>
        /// <param name="ownerEntity"></param>
        /// <param name="affectVoxels"></param>
        /// <param name="applyForceAndDamage"></param>
        /// <param name="createDecals"></param>
        /// <param name="direction">If applicable, gives the direction of the explosion, e.g. when it was caused by a missile (with its moving direction).</param>
        public void Start(ref MyExplosionInfo explosionInfo)
        {
            //MyCommonDebugUtils.AssertDebug(explosionInfo.ExplosionSphere.Radius <= MyExplosionsConstants.EXPLOSION_RADIUS_MAX);
            MyCommonDebugUtils.AssertDebug(explosionInfo.ExplosionSphere.Radius > 0);

            MyRender.GetRenderProfiler().StartProfilingBlock("MyExplosion.Start");

            m_explosionSphere       = explosionInfo.ExplosionSphere;
            m_elapsedMiliseconds    = 0;
            m_lifespanInMiliseconds = explosionInfo.LifespanMiliseconds;

            if (explosionInfo.PlaySound)
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("Sound");
                //  Play explosion sound
                if (m_explosionCue != null && m_explosionCue.Value.IsPlaying)
                {
                    m_explosionCue.Value.Stop(SharpDX.XACT3.StopFlags.Immediate);
                }
                m_explosionCue = MyAudio.AddCue3D(GetCueEnumByExplosionType(explosionInfo.ExplosionType), m_explosionSphere.Center, Vector3.Zero, Vector3.Zero, Vector3.Zero);
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            MyRender.GetRenderProfiler().StartProfilingBlock("Light");
            //  Light of explosion

            /*
             * m_light = MyLights.AddLight();
             * if (m_light != null)
             * {
             *  m_light.Start(MyLight.LightTypeEnum.PointLight, m_explosionSphere.Center, MyExplosionsConstants.EXPLOSION_LIGHT_COLOR, 1, Math.Min(m_explosionSphere.Radius * 8.0f, MyLightsConstants.MAX_POINTLIGHT_RADIUS));
             *  m_light.Intensity = 2.0f;
             * } */
            MyRender.GetRenderProfiler().EndProfilingBlock();

            // close explosion check
            bool close = IsExplosionClose(explosionInfo.ExplosionSphere);

            MyParticleEffectsIDEnum newParticlesType;

            switch (explosionInfo.ExplosionType)
            {
            case MyExplosionTypeEnum.SMALL_SHIP_EXPLOSION:
                //  Create metal debris objects thrown from the explosion
                //  This must be called before ApplyExplosionForceAndDamage (because there we apply impulses to the debris)
                //  Throw a lot of debrises, more than only if some metalic object is hit (because this is destruction of a ship)
                //MyPhysObjectExplosionDebrises.CreateExplosionDebris(m_explosionSphere.Center, 1);
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Smallship;
                break;

            case MyExplosionTypeEnum.MISSILE_EXPLOSION:
                newParticlesType =
                    // ? MyParticleEffectsIDEnum.Explosion_Missile_Close
                    MyParticleEffectsIDEnum.Explosion_Missile;
                break;

            case MyExplosionTypeEnum.BOMB_EXPLOSION:
            case MyExplosionTypeEnum.GRAVITY_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Bomb;
                break;

            case MyExplosionTypeEnum.AMMO_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Ammo;
                break;

            case MyExplosionTypeEnum.BLASTER_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Blaster;
                break;

            case MyExplosionTypeEnum.BIOCHEM_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_BioChem;
                break;

            case MyExplosionTypeEnum.EMP_EXPLOSION:
            case MyExplosionTypeEnum.FLASH_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_EMP;
                break;

            case MyExplosionTypeEnum.METEOR_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Meteor;
                break;

            case MyExplosionTypeEnum.NUCLEAR_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Nuclear;
                break;

            case MyExplosionTypeEnum.PLASMA_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Plasma;
                break;

            case MyExplosionTypeEnum.SMALL_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_SmallPrefab;
                break;

            case MyExplosionTypeEnum.LARGE_SHIP_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Huge;
                break;

            case MyExplosionTypeEnum.LARGE_PREFAB_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Large;
                break;

            case MyExplosionTypeEnum.MEDIUM_PREFAB_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Medium;
                break;

            case MyExplosionTypeEnum.ASTEROID_EXPLOSION:
                newParticlesType = MyParticleEffectsIDEnum.Explosion_Asteroid;
                break;

            default:
                throw new System.NotImplementedException();
                break;
            }


            if (explosionInfo.Damage > 0)
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("Voxel or collision");

                //  If explosion sphere intersects a voxel map, we need to cut out a sphere, spawn debrises, etc
                MyVoxelMap voxelMap = explosionInfo.AffectVoxels && explosionInfo.EmpDamage == 0 ? MyVoxelMaps.GetOverlappingWithSphere(ref m_explosionSphere) : null;
                if (voxelMap != null)
                {
                    //  Dirty explosion with a lot of dust

                    MyMwcVoxelMaterialsEnum?voxelMaterial = null;
                    float voxelContentRemovedInPercent    = 0;

                    bool createDebris = true;            // We want to create debris

                    if (explosionInfo.HitEntity != null) // but not when we hit prefab
                    {
                        createDebris &= explosionInfo.HitEntity is MyVoxelMap;
                    }


                    //cut off
                    BoundingSphere voxelExpSphere = new BoundingSphere(explosionInfo.VoxelExplosionCenter, m_explosionSphere.Radius * explosionInfo.VoxelCutoutScale);
                    if (MyVoxelGenerator.CutOutSphereFast(voxelMap, voxelExpSphere, out voxelContentRemovedInPercent, out voxelMaterial, (explosionInfo.OwnerEntity is MySmallShip && explosionInfo.OwnerEntity == Managers.Session.MySession.PlayerShip), MyFakes.VOXELS_REMOVE_RATIO))
                    {
                        if (explosionInfo.HitEntity is MyVoxelMap)
                        {
                            HUD.MyHud.ShowIndestructableAsteroidNotification();
                        }
                        createDebris = false; // and no debris when voxel is indestructible
                    }

                    //  Only if at least something was removed from voxel map
                    //  If voxelContentRemovedInPercent is more than zero than also voxelMaterial shouldn't be null, but I rather check both of them.
                    if ((voxelContentRemovedInPercent > 0) && (voxelMaterial != null))
                    {
                        //remove decals
                        MyDecals.HideTrianglesAfterExplosion(voxelMap, ref voxelExpSphere);

                        MyRender.GetRenderProfiler().StartProfilingBlock("CreateDebris");

                        if (explosionInfo.CreateDebris && (createDebris || explosionInfo.ForceDebris) && MyRenderConstants.RenderQualityProfile.ExplosionDebrisCountMultiplier > 0)
                        {
                            //  Create debris rocks thrown from the explosion
                            //  This must be called before ApplyExplosionForceAndDamage (because there we apply impulses to the debris)
                            MyExplosionDebrisVoxel.CreateExplosionDebris(ref voxelExpSphere, voxelContentRemovedInPercent, voxelMaterial.Value, explosionInfo.GroupMask, voxelMap);
                        }

                        MyRender.GetRenderProfiler().EndProfilingBlock();

                        MyRender.GetRenderProfiler().StartProfilingBlock("CreateParticleEffect");

                        MyParticleEffect explosionEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.MaterialExplosion_Destructible);
                        explosionEffect.WorldMatrix          = Matrix.CreateTranslation(voxelExpSphere.Center);
                        explosionEffect.UserRadiusMultiplier = voxelExpSphere.Radius;

                        MyRender.GetRenderProfiler().EndProfilingBlock();
                    }
                }
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            if (explosionInfo.Damage > 0)
            {
                //  Create dirt decals in player's cockpit glass
                MyRender.GetRenderProfiler().StartProfilingBlock("Cockpit Decals");
                CreateDirtDecalOnCockpitGlass(ref m_explosionSphere);
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            if (DEBUG_EXPLOSIONS)
            {
                MyRender.GetRenderProfiler().EndProfilingBlock();
                return;
            }

            if (explosionInfo.Damage > 0)
            {
                BoundingSphere influenceExplosionSphere = m_explosionSphere;
                influenceExplosionSphere.Radius *= MyExplosionsConstants.EXPLOSION_RADIUS_MULTPLIER_FOR_IMPULSE;
                for (int i = 0; i < explosionInfo.CascadeLevel; i++)
                {
                    influenceExplosionSphere.Radius *= MyExplosionsConstants.EXPLOSION_CASCADE_FALLOFF;
                }

                //  Throws surrounding objects away from centre of the explosion.
                if (explosionInfo.ApplyForceAndDamage)
                {
                    if (explosionInfo.ExplosionType == MyExplosionTypeEnum.LARGE_PREFAB_EXPLOSION ||
                        explosionInfo.ExplosionType == MyExplosionTypeEnum.LARGE_SHIP_EXPLOSION ||
                        explosionInfo.ExplosionType == MyExplosionTypeEnum.MEDIUM_PREFAB_EXPLOSION)
                    {
                        DisableContainedDummyParticles(ref explosionInfo);
                    }

                    explosionInfo.StrengthImpulse        = MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE * m_explosionSphere.Radius / 20;
                    explosionInfo.StrengthAngularImpulse = MyExplosionsConstants.EXPLOSION_STRENGTH_ANGULAR_IMPULSE;
                    explosionInfo.HitEntity = explosionInfo.HitEntity != null?explosionInfo.HitEntity.GetBaseEntity() : null;

                    MyRender.GetRenderProfiler().StartProfilingBlock("ApplyExplosionForceAndDamage");
                    MyEntities.ApplyExplosionForceAndDamage(ref explosionInfo);
                    MyRender.GetRenderProfiler().EndProfilingBlock();
                }

                //  Look for objects in explosion radius
                BoundingBox boundingBox;
                BoundingBox.CreateFromSphere(ref influenceExplosionSphere, out boundingBox);

                //if (explosionInfo.CreateDecals && explosionInfo.Direction.HasValue && explosionInfo.EmpDamage == 0)
                //{
                //    CreateDecals(explosionInfo.Direction.Value);
                //}
            }

            if (explosionInfo.CreateParticleEffect)
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("Particles");

                if (explosionInfo.CustomEffect != null)
                {
                    if (explosionInfo.CustomEffect.ParticleID == 0)
                    {
                        explosionInfo.CustomEffect.ParticleID = (int)newParticlesType;
                    }
                    //Reload effect
                    explosionInfo.CustomEffect.Enabled = false;
                    explosionInfo.CustomEffect.Enabled = true;
                }
                else
                {
                    //  Explosion particles
                    GenerateExplosionParticles(newParticlesType, m_explosionSphere, explosionInfo.ParticleScale);
                }

                MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            MyRender.GetRenderProfiler().EndProfilingBlock();

            /*
             *  // When MyAmmoBase entity is closed to explosion it will explode
             *  if (entity is MyAmmoBase)
             *  {
             *      (entity as MyAmmoBase).ExplodeCascade(cascadeLevel + 1);
             *  }
             */

            //  Smut decals - must be called after the explosion, after voxels are cutted out

            /*if ((intersection.PhysObject is MyVoxelMap) == false)
             * {
             *  if (intersection.PhysObject is MyCockpitGlass)
             *  {
             *      //  Change phys object so rest of the code will think we hit the parent
             *      //  Same fix is in projectile too - because cockpit glass is only helper object, we don't use it for real rendering and stuff
             *      //  And if not changed, it can make problem in "phys object decals"
             *      intersection.PhysObject = intersection.PhysObject.Parent;
             *  }
             *
             *  //  Create explosion smut decal on model we hit by this missile
             *  MyDecals.Add(
             *      MyDecalTexturesEnum.ExplosionSmut,
             *      MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.7f, m_explosionSphere.Radius * 1.3f),
             *      MyMwcUtils.GetRandomRadian(),
             *      GetSmutDecalRandomColor(),
             *      true,
             *      ref intersection);
             * }
             * else
             * {
             *  //  Creating explosion smut decal on voxel is more complicated than on voxel. We will project few lines
             *  //  from explosion epicentrum to the surounding world (random directions) and place decal where intersection detected.
             *  //if (knownMissileDirection != null)
             *  //{
             *  //    MyLine linePrologned = new MyLine(knownIntersection.Value.IntersectionPointInObjectSpace,
             *  //        knownIntersection.Value.IntersectionPointInObjectSpace + knownMissileDirection.Value * MyExplosionsConstants.EXPLOSION_RANDOM_RADIUS_MAX * 2,
             *  //        true);
             *  //    MyLineTriangleIntersectionResult intersectionForSmut = knownIntersection.Value.VoxelMap.GetIntersectionWithLine(ref linePrologned);
             *  //    if (intersectionForSmut.Found == true)
             *  //    {
             *  //        MyDecals.Add(
             *  //            MyDecalTexturesEnum.ExplosionSmut,
             *  //            MyMwcUtils.GetRandomFloat(m_explosionSphere.Radius * 0.5f, m_explosionSphere.Radius * 1.0f),
             *  //            MyMwcUtils.GetRandomRadian(),
             *  //            GetSmutDecalRandomColor(),
             *  //            false,
             *  //            ref intersectionForSmut);
             *  //    }
             *  //}
             * }*/

            //  Generate dust particles that will stay in place of the explosion
            //doesnt look good in final
            //GenerateStatisDustParticles(m_explosionSphere);
        }
示例#12
0
        //  Called when we finished harvesting current voxel
        void StartReleaseVoxel()
        {
            if (m_parentMinerShip == null || m_parentMinerShip.IsDead() || m_parentMinerShip.Inventory == null)
            {
                return;
            }

            StartImplodeCue();
            BoundingSphere explosion = new BoundingSphere(m_headPositionTransformed, MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1);

            //remove decals
            MyDecals.HideTrianglesAfterExplosion(m_inVoxelMap, ref explosion);
            //cut off

            var minedMaterialsWithContents = MyVoxelGenerator.CutOutSphereFastWithMaterials(m_inVoxelMap, explosion);

            var dustEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Harvester_Finished);

            dustEffect.WorldMatrix = Matrix.CreateTranslation(m_headPositionTransformed);

            bool hudHarvestingCompletePlayed = false;
            bool harvestingFinishedAsyncSent = false;

            var minedOres = new Dictionary <int, float>();

            foreach (var minedMaterialWithContent in minedMaterialsWithContents)
            {
                MyOreRatioFromVoxelMaterial[] oreFromVoxel = MyVoxelMapOreMaterials.GetOreFromVoxelMaterial(minedMaterialWithContent.Key);
                if (oreFromVoxel != null && this.Parent == MySession.PlayerShip)
                {
                    // accumulate amounts of the same type
                    foreach (MyOreRatioFromVoxelMaterial oreRatio in oreFromVoxel)
                    {
                        float amount    = minedMaterialWithContent.Value * oreRatio.Ratio * MyHarvestingTubeConstants.MINED_CONTENT_RATIO;
                        float oldAmount = 0;
                        minedOres.TryGetValue((int)oreRatio.OreType, out oldAmount);
                        minedOres[(int)oreRatio.OreType] = amount + oldAmount;
                    }

                    if (!harvestingFinishedAsyncSent)
                    {
                        try
                        {
                            // Disabled, still unused on server
                            //var client = MySectorServiceClient.GetCheckedInstance();
                            //client.HarvestingFinishedAsync(minedMaterialWithContent.Key, (byte)(minedMaterialWithContent.Value * MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT));
                        }
                        catch (Exception)
                        {
                            Debug.Fail("Cannot send harvesting to server");
                        }
                        harvestingFinishedAsyncSent = true;
                    }

                    if (!hudHarvestingCompletePlayed)
                    {
                        hudHarvestingCompletePlayed = true;
                        MyAudio.AddCue2D(MySoundCuesEnum.HudHarvestingComplete);
                    }
                }
            }


            bool inventoryFullWarningPlayed = false;

            // add ores to inventory
            foreach (var ore in minedOres)
            {
                float amountLeft = m_parentMinerShip.Inventory.AddInventoryItem(MyMwcObjectBuilderTypeEnum.Ore, ore.Key, ore.Value, false);

                float amountAdded = ore.Value - amountLeft;
                if (amountAdded > 0f)
                {
                    MyHudNotification.AddNotification(new MyHudNotification.MyNotification(MyTextsWrapperEnum.HarvestNotification, 3500, textFormatArguments: new object[]
                    {
                        amountAdded,
                        ((MyGuiOreHelper)MyGuiObjectBuilderHelpers.GetGuiHelper(MyMwcObjectBuilderTypeEnum.Ore, ore.Key)).Name
                    }
                                                                                           ));
                }

                if (amountLeft > 0f)
                {
                    MyHudNotification.AddNotification(new MyHudNotification.MyNotification(MyTextsWrapperEnum.HarvestNotificationInventoryFull, MyGuiManager.GetFontMinerWarsRed(), 3500,
                                                                                           textFormatArguments: new object[]
                    {
                        amountLeft,
                        ((MyGuiOreHelper)MyGuiObjectBuilderHelpers.GetGuiHelper(MyMwcObjectBuilderTypeEnum.Ore, ore.Key)).Name
                    }
                                                                                           ));
                    if (!inventoryFullWarningPlayed)
                    {
                        MyAudio.AddCue2D(MySoundCuesEnum.HudInventoryFullWarning);
                        inventoryFullWarningPlayed = true;
                    }
                }
            }

            StartReturningBack();
        }
示例#13
0
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();

            bool isShooting = IsShooting;

            if (!m_isHit && IsShooting && (MySandboxGame.Static.UpdateTime - m_lastShot > MyTimeSpan.FromSeconds(m_shotToolAction.Value.HitStart)))
            {
                IMyHandToolComponent toolComponent;
                if (m_toolComponents.TryGetValue(m_shotHitCondition.Component, out toolComponent))
                {
                    MyCharacterDetectorComponent detectorComponent = m_owner.Components.Get <MyCharacterDetectorComponent>();
                    if (detectorComponent != null)
                    {
                        if (m_shotToolAction.Value.CustomShapeRadius > 0 && detectorComponent is MyCharacterShapecastDetectorComponent)
                        {
                            var shapeCastComponent = detectorComponent as MyCharacterShapecastDetectorComponent;
                            shapeCastComponent.ShapeRadius = m_shotToolAction.Value.CustomShapeRadius;
                            shapeCastComponent.DoDetectionModel();
                            shapeCastComponent.ShapeRadius = MyCharacterShapecastDetectorComponent.DEFAULT_SHAPE_RADIUS;
                        }

                        if (detectorComponent.DetectedEntity != null)
                        {
                            MyHitInfo hitInfo = new MyHitInfo();
                            hitInfo.Position = detectorComponent.HitPosition;
                            hitInfo.Normal   = detectorComponent.HitNormal;

                            bool  isBlock = false;
                            float efficiencyMultiplier = 1.0f;
                            bool  canHit = CanHit(toolComponent, detectorComponent, ref isBlock, out efficiencyMultiplier);

                            MyDecals.HandleAddDecal(detectorComponent.DetectedEntity, hitInfo, MyDamageType.Weapon);

                            bool isHit = false;
                            if (canHit)
                            {
                                if (!string.IsNullOrEmpty(m_shotToolAction.Value.StatsEfficiency) && Owner.StatComp != null)
                                {
                                    efficiencyMultiplier *= Owner.StatComp.GetEfficiencyModifier(m_shotToolAction.Value.StatsEfficiency);
                                }

                                float efficiency = m_shotToolAction.Value.Efficiency * efficiencyMultiplier;
                                var   tool       = detectorComponent.DetectedEntity as MyHandToolBase;
                                if (isBlock && tool != null)
                                {
                                    isHit = toolComponent.Hit(tool.Owner, hitInfo, detectorComponent.ShapeKey, efficiency);
                                }
                                else
                                {
                                    isHit = toolComponent.Hit((MyEntity)detectorComponent.DetectedEntity, hitInfo, detectorComponent.ShapeKey, efficiency);
                                }

                                if (isHit && Sync.IsServer && Owner.StatComp != null)
                                {
                                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsActionIfHit))
                                    {
                                        Owner.StatComp.DoAction(m_shotHitCondition.StatsActionIfHit);
                                    }
                                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsModifierIfHit))
                                    {
                                        Owner.StatComp.ApplyModifier(m_shotHitCondition.StatsModifierIfHit);
                                    }
                                }
                            }

                            if (canHit || isBlock)  // real hit is not controlled now - there isn't any server-client synchronization of hit currently and hit is performed only at server
                            {
                                if (!string.IsNullOrEmpty(m_shotToolAction.Value.HitSound))
                                {
                                    PlaySound(m_shotToolAction.Value.HitSound);
                                }
                                else
                                {
                                    MyStringId collisionType = MyMaterialPropertiesHelper.CollisionType.Hit;
                                    bool       showParticles = false;

                                    // If it didn't play the Sound with "Hit", it will try with "Start"
                                    if (MyAudioComponent.PlayContactSound(EntityId, m_hitCue, detectorComponent.HitPosition,
                                                                          m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial))
                                    {
                                        showParticles = true;
                                    }
                                    else if (MyAudioComponent.PlayContactSound(EntityId, m_startCue, detectorComponent.HitPosition,
                                                                               m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial))
                                    {
                                        showParticles = true;
                                        collisionType = MyMaterialPropertiesHelper.CollisionType.Start;
                                    }

                                    if (showParticles)
                                    {
                                        MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(
                                            collisionType,
                                            detectorComponent.HitPosition,
                                            detectorComponent.HitNormal,
                                            m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial);
                                    }
                                }

                                this.RaiseEntityEvent(MyStringHash.GetOrCompute("Hit"), new MyEntityContainerEventExtensions.HitParams(MyStringHash.GetOrCompute(m_shotHitCondition.Component), detectorComponent.HitMaterial));
                                m_soundEmitter.StopSound(true);
                            }
                        }
                    }
                }

                m_isHit = true;
            }

            if (!m_swingSoundPlayed && IsShooting && !m_isHit && (MySandboxGame.Static.UpdateTime - m_lastShot > MyTimeSpan.FromSeconds(m_shotToolAction.Value.SwingSoundStart)))
            {
                if (!string.IsNullOrEmpty(m_shotToolAction.Value.SwingSound))
                {
                    PlaySound(m_shotToolAction.Value.SwingSound);
                }
                m_swingSoundPlayed = true;
            }


            if (!isShooting && m_wasShooting)
            {
                m_owner.StopUpperCharacterAnimation(0.4f);
                m_shotToolAction = null;
            }


            m_wasShooting = isShooting;

            if (m_owner != null)
            {
                MatrixD blockingMatrix = MatrixD.CreateWorld(((MyEntity)m_owner.CurrentWeapon).PositionComp.GetPosition(), m_owner.WorldMatrix.Forward, m_owner.WorldMatrix.Up);

                ((MyBlockingBody)Physics).SetWorldMatrix(blockingMatrix);
            }


            foreach (var c in m_toolComponents.Values)
            {
                c.Update();
            }
        }
示例#14
0
        /// <summary>
        /// Updates resource.
        /// </summary>
        public override void UpdateBeforeSimulation()
        {
            try
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation");

                if (m_isExploded)
                {
                    if (Sandbox.Game.Multiplayer.Sync.IsServer)
                    {
                        //  Create explosion
                        float           radius          = m_missileAmmoDefinition.MissileExplosionRadius;
                        BoundingSphereD explosionSphere = new BoundingSphereD(m_collisionPoint.HasValue ? m_collisionPoint.Value : PositionComp.GetPosition(), radius);

                        MyEntity ownerEntity = null;
                        var      ownerId     = Sync.Players.TryGetIdentity(m_owner);
                        if (ownerId != null)
                        {
                            ownerEntity = ownerId.Character;
                        }
                        //MyEntities.TryGetEntityById(m_owner, out ownerEntity);


                        //  Call main explosion starter
                        MyExplosionInfo info = new MyExplosionInfo()
                        {
                            PlayerDamage = 0,
                            //Damage = m_ammoProperties.Damage,
                            Damage              = MyFakes.ENABLE_VOLUMETRIC_EXPLOSION ? m_missileAmmoDefinition.MissileExplosionDamage : 200,
                            ExplosionType       = m_explosionType,
                            ExplosionSphere     = explosionSphere,
                            LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN,
                            CascadeLevel        = CascadedExplosionLevel,
                            HitEntity           = m_collidedEntity,
                            ParticleScale       = 0.2f,
                            OwnerEntity         = ownerEntity,

                            Direction            = WorldMatrix.Forward,
                            VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.25f,

                            ExplosionFlags      = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION,
                            VoxelCutoutScale    = 0.3f,
                            PlaySound           = true,
                            ApplyForceAndDamage = true
                        };
                        if (!MarkedToDestroy)
                        {
                            info.ExplosionFlags |= MyExplosionFlags.CREATE_PARTICLE_EFFECT;
                        }
                        MyExplosions.AddExplosion(ref info);

                        if (m_collidedEntity != null && !(m_collidedEntity is MyAmmoBase))
                        {
                            if (!m_collidedEntity.Physics.IsStatic)
                            {
                                m_collidedEntity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                                                                  100 * Physics.LinearVelocity, m_collisionPoint, null);
                            }
                        }
                    }

                    //by Gregory: added null check. Decal won't be added if m_collidedEntity not found
                    if (m_collisionPoint.HasValue && m_collidedEntity != null)
                    {
                        MyHitInfo hitInfo = new MyHitInfo();
                        hitInfo.Position = m_collisionPoint.Value;
                        hitInfo.Normal   = new Vector3D(1, 0, 0); // FIXME

                        MyDecals.HandleAddDecal(m_collidedEntity, hitInfo, MyDamageType.Rocket);
                    }

                    Close();

                    return;
                }

                base.UpdateBeforeSimulation();

                if (m_missileAmmoDefinition.MissileSkipAcceleration)
                {
                    Physics.LinearVelocity = WorldMatrix.Forward * m_missileAmmoDefinition.DesiredSpeed * 0.7f;
                }
                else
                {
                    Physics.LinearVelocity += PositionComp.WorldMatrix.Forward * m_missileAmmoDefinition.MissileAcceleration * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
                }

                if (m_smokeEffect == null)
                {
                    // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150)
                    {
                        if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile, out m_smokeEffect))
                        {
                            m_smokeEffect.UserScale = 0.3f;

                            var matrix = PositionComp.WorldMatrix;
                            matrix.Translation       -= matrix.Forward * m_smokeEffectOffsetMultiplier;
                            m_smokeEffect.WorldMatrix = matrix;
                            //m_smokeEffect.WorldMatrix = PositionComp.WorldMatrix;
                            m_smokeEffect.AutoDelete           = false;
                            m_smokeEffect.CalculateDeltaMatrix = true;
                        }
                    }
                }
                Physics.AngularVelocity = Vector3.Zero;

                if ((Vector3.Distance(PositionComp.GetPosition(), m_origin) >= m_maxTrajectory))
                {
                    Explode();
                    return;
                }
            }
            finally
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
示例#15
0
        /// <summary>
        /// Every object must have this method, but not every phys object must necessarily have something to cleanup
        /// <remarks>
        /// </remarks>
        /// </summary>
        public void Delete()
        {
            Close();
            BeforeDelete();
            GameLogic.Close();
            //doesnt work in parallel update
            //Debug.Assert(MySandboxGame.IsMainThread(), "Entity.Close() called not from Main Thread!");
            Debug.Assert(MyEntities.UpdateInProgress == false, "Do not close entities directly in Update*, use MarkForClose() instead");
            Debug.Assert(MyEntities.CloseAllowed == true, "Use MarkForClose()");
            Debug.Assert(!Closed, "Close() called twice!");

            //Children has to be cleared after close notification is send
            while (Hierarchy.Children.Count > 0)
            {
                MyHierarchyComponentBase compToRemove = Hierarchy.Children[Hierarchy.Children.Count - 1];
                Debug.Assert(compToRemove.Parent != null, "Entity has no parent but is part of children collection");

                compToRemove.Entity.Delete();

                Hierarchy.Children.Remove(compToRemove);
            }

            //OnPositionChanged = null;

            CallAndClearOnClosing();

            MyDecals.RemoveModelDecals(this);
            MyEntities.RemoveName(this);
            MyEntities.RemoveFromClosedEntities(this);

            if (m_physics != null)
            {
                m_physics.Close();
                Physics = null;

                RaisePhysicsChanged();
            }

            MyEntities.UnregisterForUpdate(this, true);


            if (Parent == null) //only root objects are in entities list
            {
                MyEntities.Remove(this);
            }
            else
            {
                Parent.Hierarchy.Children.Remove(this.Hierarchy);

                //remove children first
                if (Parent.InScene)
                {
                    OnRemovedFromScene(this);
                }

                MyEntities.RaiseEntityRemove(this);
            }

            if (this.EntityId != 0)
            {
                MyEntityIdentifier.RemoveEntity(this.EntityId);
            }

            //this.EntityId = 0;
            Debug.Assert(this.Hierarchy.Children.Count == 0);

            CallAndClearOnClose();

            Components.Clear();

            Closed = true;
        }
示例#16
0
        //public void CloseDetector()
        //{
        //    m_targetsDetector.Close();
        //}

        public override void Close()
        {
            MyDecals.RemoveModelDecals(m_gun);
            base.Close();
        }
示例#17
0
        //  Update position, check collisions, etc.
        //  Return false if projectile dies/timeouts in this tick.
        public bool Update()
        {
            //  Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw)
            if (m_state == MyProjectileStateEnum.KILLED)
            {
                return(true);
            }
            //  Projectile was killed and last time drawn, so we can finally remove it from buffer
            if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN)
            {
                StopEffect();
                return(false);
            }

            Vector3D position = m_position;

            m_position += m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED;

            //  Distance timeout
            Vector3 positionDelta = m_position - m_origin;

            if (Vector3.Dot(positionDelta, positionDelta) >= m_maxTrajectory * m_maxTrajectory)
            {
                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
                return(true);
            }

            m_checkIntersectionIndex = ++m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL;
            if (m_checkIntersectionIndex != 0 && m_positionChecked) //check only each n-th intersection
            {
                return(true);
            }

            //  Calculate hit point, create decal and throw debris particles
            Vector3D lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED);

            LineD line = new LineD(m_positionChecked ? position : m_origin, lineEndPosition);

            m_positionChecked = true;

            IMyEntity entity;
            MyHitInfo hitInfo;
            object    customdata;

            GetHitEntityAndPosition(line, out entity, out hitInfo, out customdata);
            if (entity == null || entity.Physics == null)
            {
                return(true);
            }

            if (IsIgnoredEntity(entity))
            {
                return(true); // prevent player shooting himself
            }

            ProfilerShort.Begin("Projectile.Update");

            bool        headShot     = false;
            MyCharacter hitCharacter = entity as MyCharacter;

            if (hitCharacter != null)
            {
                IStoppableAttackingTool stoppableTool = hitCharacter.CurrentWeapon as IStoppableAttackingTool;
                if (stoppableTool != null)
                {
                    stoppableTool.StopShooting(OwnerEntity);
                }

                headShot = (customdata as MyCharacterHitInfo).HitHead && m_projectileAmmoDefinition.HeadShot; // allow head shots only for ammo supporting it in definition
            }

            m_position = hitInfo.Position;

            bool isProjectileGroupKilled = false;

            if (!isProjectileGroupKilled)
            {
                MySurfaceImpactEnum surfaceImpact;
                MyStringHash        materialType;
                GetSurfaceAndMaterial(entity, ref line, ref hitInfo.Position, out surfaceImpact, out materialType);

                PlayHitSound(materialType, entity, hitInfo.Position, m_projectileAmmoDefinition.PhysicalMaterial);

                hitInfo.Velocity = m_velocity;

                float damage = entity is IMyCharacter ? (headShot ? m_projectileAmmoDefinition.ProjectileHeadShotDamage : m_projectileAmmoDefinition.ProjectileHealthDamage) : m_projectileAmmoDefinition.ProjectileMassDamage;
                DoDamage(damage, hitInfo, customdata, entity);

                MyDecals.HandleAddDecal(entity, hitInfo, materialType, m_projectileAmmoDefinition.PhysicalMaterial, (customdata as MyCharacterHitInfo), damage);

                //particle effect defined in materialProperties.sbc
                Vector3D particleHitPosition = hitInfo.Position + (Vector3D)line.Direction * -0.2;
                bool     createdEffect       = MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(MyMaterialPropertiesHelper.CollisionType.Hit, particleHitPosition, hitInfo.Normal, m_projectileAmmoDefinition.PhysicalMaterial, materialType);
                if (!createdEffect && surfaceImpact != MySurfaceImpactEnum.CHARACTER)
                {
                    MyParticleEffects.CreateBasicHitParticles(m_projectileAmmoDefinition.ProjectileOnHitEffectName, ref hitInfo.Position, ref hitInfo.Normal, ref line.Direction, entity, m_weapon, 1, OwnerEntity);
                }

                CreateDecal(materialType);

                if (m_weapon == null || (entity.GetTopMostParent() != m_weapon.GetTopMostParent()))
                {
                    ApplyProjectileForce(entity, hitInfo.Position, m_directionNormalized, false, m_projectileAmmoDefinition.ProjectileHitImpulse * m_impulseMultiplier);
                }

                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
            }
            ProfilerShort.End();
            return(true);
        }
示例#18
0
        //  Update position, check collisions, etc.
        //  Return false if projectile dies/timeouts in this tick.
        public bool Update()
        {
            //  Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw)
            if (m_state == MyProjectileStateEnum.KILLED)
            {
                return(true);
            }

            //  Projectile was killed and last time drawn, so we can finally remove it from buffer
            if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN)
            {
                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                return(false);
            }

            Vector3 position = m_position;

            m_position += m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            m_velocity  = m_externalVelocity * m_externalAddition + m_directionNormalized * m_speed;
            if (m_externalAddition < 1.0f)
            {
                m_externalAddition *= 0.5f;
            }

            //  Distance timeout
            float trajectoryLength = Vector3.Distance(m_position, m_origin);

            if (trajectoryLength >= m_maxTrajectory)
            {
                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                m_state = MyProjectileStateEnum.KILLED;
                return(true);
            }

            if (m_trailEffect != null)
            {
                m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position);
            }

            m_checkIntersectionIndex++;
            m_checkIntersectionIndex = m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL;

            //check only each n-th intersection
            if (m_checkIntersectionIndex != 0)
            {
                return(true);
            }

            //  Calculate hit point, create decal and throw debris particles
            Vector3 lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS);

            MyLine line = new MyLine(m_positionChecked ? position : m_origin, lineEndPosition, true);

            m_positionChecked = true;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()");
            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignorePhysObject, null, false);

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MyEntity physObject = intersection != null ? intersection.Value.Entity : null;

            if (physObject != null)
            {
                while (physObject.Physics == null && physObject.Parent != null)
                {
                    physObject = physObject.Parent;
                }
            }

            if ((intersection != null) && (physObject != null) && (physObject.Physics.CollisionLayer != MyConstants.COLLISION_LAYER_UNCOLLIDABLE) && m_ignorePhysObject != physObject)
            {
                MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value;

                bool isPlayerShip = MySession.PlayerShip == physObject;

                MyMaterialType materialType = isPlayerShip ? MyMaterialType.PLAYERSHIP : physObject.Physics.MaterialType;

                //material properties
                MyMaterialTypeProperties materialProperties = MyMaterialsConstants.GetMaterialProperties(materialType);

                bool isProjectileGroupKilled = false;

                if (m_sharedGroup != null)
                {
                    isProjectileGroupKilled = m_sharedGroup.Killed;
                    m_sharedGroup.Killed    = true;
                }

                if (!isProjectileGroupKilled)
                {
                    //  Play bullet hit cue
                    MyAudio.AddCue3D(m_ammoProperties.IsExplosive ? materialProperties.ExpBulletHitCue : materialProperties.BulletHitCue, intersectionValue.IntersectionPointInWorldSpace, Vector3.Zero, Vector3.Zero, Vector3.Zero);
                }

                float decalAngle = MyMwcUtils.GetRandomRadian();

                //  If we hit the glass of a miner ship, we need to create special bullet hole decals
                //  drawn from inside the cockpit and change phys object so rest of the code will think we hit the parent
                //  IMPORTANT: Intersection between projectile and glass is calculated only for mining ship in which player sits. So for enemies this will be never calculated.
                if (intersection.Value.Entity is MyCockpitGlassEntity)
                {
                    if (!isProjectileGroupKilled)
                    {
                        MyCockpitGlassDecalTexturesEnum bulletHoleDecalTexture;
                        float bulletHoleDecalSize;

                        if (MyMwcUtils.GetRandomBool(3))
                        {
                            bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleOnGlass;
                            bulletHoleDecalSize    = 0.25f;
                        }
                        else
                        {
                            bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleSmallOnGlass;
                            bulletHoleDecalSize    = 0.1f;
                        }

                        //  Place bullet hole decal on player's cockpit glass (seen from inside the ship)
                        MyCockpitGlassDecals.Add(bulletHoleDecalTexture, bulletHoleDecalSize, decalAngle, 1.0f, ref intersectionValue, false);

                        //  Create hit particles throwed into the cockpit (it's simulation of broken glass particles)
                        //  IMPORTANT: This particles will be relative to miner ship, so we create them in object space coordinates and update them by object WorldMatrix every time we draw them
                        //MyParticleEffects.CreateHitParticlesGlass(ref intersectionValue.IntersectionPointInObjectSpace, ref intersectionValue.NormalInWorldSpace, ref line.Direction, physObject.Parent);
                    }
                }

                //  If this was "mine", it must explode
                else if (physObject is MyMineBase)
                {
                    m_state = MyProjectileStateEnum.KILLED;
                    if (!IsDummy)
                    {
                        (physObject as MyAmmoBase).Explode();
                    }
                    return(true);
                }

                //  If this was missile, cannon shot, it must explode if it is not mine missile
                else if (physObject is MyAmmoBase)
                {
                    if (((MyAmmoBase)physObject).OwnerEntity == m_ignorePhysObject)
                    {
                        m_state = MyProjectileStateEnum.KILLED;
                        if (!IsDummy)
                        {
                            (physObject as MyAmmoBase).Explode();
                        }
                        return(true);
                    }
                }

                else if (this.OwnerEntity is MySmallShip && (MySmallShip)this.OwnerEntity == MySession.PlayerShip && physObject is MyStaticAsteroid && !physObject.IsDestructible)
                {
                    if (this.m_ammoProperties.IsExplosive || (this.m_ammoProperties.AmmoType == MyAmmoType.Explosive && this.m_weapon is Weapons.MyShotGun))
                    {
                        HUD.MyHud.ShowIndestructableAsteroidNotification();
                    }
                }

                else if (!isProjectileGroupKilled && !isPlayerShip)
                {
                    //  Create smoke and debris particle at the place of voxel/model hit
                    m_ammoProperties.OnHitParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, m_weapon, OwnerEntity);

                    MySurfaceImpactEnum surfaceImpact;
                    if (intersectionValue.Entity is MyVoxelMap)
                    {
                        var voxelMap   = intersectionValue.Entity as MyVoxelMap;
                        var voxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref intersectionValue.IntersectionPointInWorldSpace);
                        var material   = voxelMap.GetVoxelMaterial(ref voxelCoord);
                        if (material == MyMwcVoxelMaterialsEnum.Indestructible_01 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_02 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_03 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_04 ||
                            material == MyMwcVoxelMaterialsEnum.Indestructible_05_Craters_01)
                        {
                            surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE;
                        }
                        else
                        {
                            surfaceImpact = MySurfaceImpactEnum.DESTRUCTIBLE;
                        }
                    }
                    else if (intersectionValue.Entity is MyStaticAsteroid)
                    {
                        surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE;
                    }
                    else
                    {
                        surfaceImpact = MySurfaceImpactEnum.METAL;
                    }

                    m_ammoProperties.OnHitMaterialSpecificParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, surfaceImpact, m_weapon);
                }

                if (!(physObject is MyExplosionDebrisBase) && physObject != MySession.PlayerShip)
                {
                    //  Decal size depends on material. But for mining ship create smaller decal as original size looks to large on the ship.
                    float decalSize = MyMwcUtils.GetRandomFloat(materialProperties.BulletHoleSizeMin,
                                                                materialProperties.BulletHoleSizeMax);

                    //  Place bullet hole decal
                    float randomColor = MyMwcUtils.GetRandomFloat(0.5f, 1.0f);

                    MyDecals.Add(
                        materialProperties.BulletHoleDecal,
                        decalSize,
                        decalAngle,
                        new Vector4(randomColor, randomColor, randomColor, 1),
                        false,
                        ref intersectionValue,
                        0.0f,
                        m_ammoProperties.DecalEmissivity, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL);
                }

                if (!(physObject is MyVoxelMap) && !IsDummy)
                {
                    ApplyProjectileForce(physObject, intersectionValue.IntersectionPointInWorldSpace, m_directionNormalized, isPlayerShip);
                }


                //  If this object is miner ship, then shake his head little bit
                if (physObject is MySmallShip && !IsDummy)
                {
                    MySmallShip minerShip = (MySmallShip)physObject;
                    minerShip.IncreaseHeadShake(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_AFTER_PROJECTILE_HIT);
                }



                //Handle damage

                MyEntity damagedObject = intersectionValue.Entity;

                // not a very nice way to damage actual prefab associated with the large ship weapon (if MyPrefabLargeWeapon is reworked, it might change)
                if (damagedObject is MyLargeShipBarrelBase)
                {
                    damagedObject = damagedObject.Parent;
                }
                if (damagedObject is MyLargeShipGunBase)
                {
                    MyLargeShipGunBase physObj = damagedObject as MyLargeShipGunBase;
                    if (physObj.PrefabParent != null)
                    {
                        damagedObject = physObj.PrefabParent;
                    }
                }

                //  Decrease health of stricken object
                if (!IsDummy)
                {
                    damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject);
                    if (MyMultiplayerGameplay.IsRunning)
                    {
                        var ammo = MyAmmoConstants.FindAmmo(m_ammoProperties);
                        MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, ammo, this.OwnerEntity);
                    }
                }

                if (m_trailEffect != null)
                {
                    // stop the trail effect
                    m_trailEffect.Stop();
                    m_trailEffect = null;
                }

                //  Kill this projectile (set the position to intersection point, so we draw trail polyline only up to this point)
                m_position = intersectionValue.IntersectionPointInWorldSpace;
                m_state    = MyProjectileStateEnum.KILLED;

                return(true);
            }

            return(true);
        }
示例#19
0
        private void DoDamage(float damage, MyHitInfo hitInfo, object customdata, IMyEntity damagedEntity)
        {
            //damage tracking
            MyEntity ent = (MyEntity)MySession.Static.ControlledEntity;

            if (this.OwnerEntityAbsolute != null && this.OwnerEntityAbsolute.Equals(MySession.Static.ControlledEntity) && (damagedEntity is IMyDestroyableObject || damagedEntity is MyCubeGrid))
            {
                MySession.Static.TotalDamageDealt += (uint)damage;
            }

            MyDecals.HandleAddDecal(damagedEntity, hitInfo, m_projectileAmmoDefinition.PhysicalMaterial, customdata, damage);

            if (!Sync.IsServer)
            {
                return;
            }

            if (m_projectileAmmoDefinition.PhysicalMaterial == m_hashBolt)
            {
                IMyDestroyableObject destroyable = damagedEntity as IMyDestroyableObject;
                if (destroyable != null && damagedEntity is MyCharacter)
                {
                    destroyable.DoDamage(damage, MyDamageType.Bolt, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
                }
            }
            else
            {
                var grid = damagedEntity as MyCubeGrid;
                IMyDestroyableObject destroyable;
                if (grid != null)
                {
                    if (grid.Physics != null && grid.Physics.Enabled && (grid.BlocksDestructionEnabled || MyFakes.ENABLE_VR_FORCE_BLOCK_DESTRUCTIBLE))
                    {
                        bool causeDeformation = false;
                        var  block            = grid.GetTargetedBlock(hitInfo.Position);
                        if (block != null && (grid.BlocksDestructionEnabled || block.ForceBlockDestructible))
                        {
                            block.DoDamage(damage, MyDamageType.Bullet, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
                            if (block.FatBlock == null)
                            {
                                causeDeformation = true;
                            }
                        }

                        if (grid.BlocksDestructionEnabled && causeDeformation)
                        {
                            ApllyDeformationCubeGrid(hitInfo.Position, grid);
                        }
                    }
                }
                //By Gregory: When MyEntitySubpart (e.g. extended parts of pistons and doors) damage the whole parent component
                //Temporary fix! Maybe other solution? MyEntitySubpart cannot implement IMyDestroyableObject cause is on dependent namespace
                else if (damagedEntity is MyEntitySubpart)
                {
                    if (damagedEntity.Parent != null && damagedEntity.Parent.Parent is MyCubeGrid)
                    {
                        hitInfo.Position = damagedEntity.Parent.WorldAABB.Center;
                        DoDamage(damage, hitInfo, customdata, damagedEntity.Parent.Parent);
                    }
                }
                else if ((destroyable = damagedEntity as IMyDestroyableObject) != null)
                {
                    destroyable.DoDamage(damage, MyDamageType.Bullet, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
                }
            }

            //Handle damage ?? some WIP code by Ondrej
            //MyEntity damagedObject = entity;
            //damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject);
            //if (MyMultiplayerGameplay.IsRunning)
            //    MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, MyAmmoConstants.FindAmmo(m_ammoProperties), this.OwnerEntity);
        }