void m_transporter_OnContactEvent(MyEntity obj)
 {
     //Damage all bot which touched our mothership (we have to prevent sticking bots to ms because of physics)
     if (obj is MySmallShipBot)
     {
         obj.DoDamage(0, 5, 0, MyDamageType.Unknown, MyAmmoType.Unknown, m_transporter);
     }
 }
 private void ScannerOnOnEntityScanned(MyPrefabScanner sender, MyEntity scannedEntity)
 {
     if (scannedEntity == MySession.PlayerShip && m_scanners.Contains(sender))
     {
         scannedEntity.DoDamage(0, 1000000, 0, MyDamageType.Unknown, MyAmmoType.Unknown, null);
         ((MyPrefabContainer)sender.Parent).AlarmOn = true;
     }
 }
Beispiel #3
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);
        }
Beispiel #4
0
        protected override void Drill()
        {
            //  Sphere which is used to make tunnel to voxel and sphere for testing collision with voxel
            m_fakeCollisionSphere = new BoundingSphere(m_fakeSpherePositionTransformed, m_radius);
            //  Check for collision with drill and world
            //MyEntity collisionResult = MyEntities.GetIntersectionWithSphere(ref m_fakeCollisionSphere, this, Parent, false, true);
            // bSphere collision doesn't work - the sphere is tested against LOD0 model, but it is hidden inside the COL model and the bSphere is too small to reach it - so I use line instead

            MyEntity collisionResult = null;
            MyLine   line;

            if (MySession.Is25DSector)
            {
                line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 20 * WorldMatrix.Forward, true);
            }
            else
            {
                line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 5 * WorldMatrix.Forward, true);
            }

            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, Parent, this, true, true);

            if (intersection != null && intersection.Value.Entity.Physics != null)
            {
                collisionResult = intersection.Value.Entity;
            }

            if (!(collisionResult is MyVoxelMap))
            {
                m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds = MyMinerGame.TotalGamePlayTimeInMilliseconds;

                if (!MySession.Is25DSector)
                {
                    ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_ROTATION);
                }

                StopDustEffect();

                if (collisionResult != null)
                {
                    var effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.MaterialHit_Autocannon_Metal);
                    effect.WorldMatrix = Matrix.CreateTranslation(m_fakeCollisionSphere.Center);
                    collisionResult.DoDamage(0, m_damage * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS, 0, MyDamageType.Drill, MyAmmoType.Basic, Parent);
                }
            }
            //  Display particles when we are in contact with voxel
            else
            {
                if (m_dustEffect == null)
                {
                    m_dustEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_DrillDust);
                }
                m_dustEffect.WorldMatrix = Matrix.CreateTranslation(m_fakeSpherePositionTransformed);
                m_dustEffect.UserScale   = MySession.Is25DSector ? 3 : 1;
                ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_IN_VOXELS);
            }

            //  Play sound if there is collision with voxel
            if (collisionResult != null)
            {
                if (collisionResult is MyStaticAsteroid)
                {
                    if (!collisionResult.IsDestructible)
                    {
                        MinerWars.AppCode.Game.HUD.MyHud.ShowIndestructableAsteroidNotification();
                    }
                }
                StartDrillingCue(collisionResult is MyVoxelMap);
                StopMovingCue();
            }
            else
            {
                StartMovingCue();
                StopDrillingCue();
            }

            //  We found voxel so lets make tunel into it
            using (var voxelMapsFound = PoolList <MyVoxelMap> .Get())
            {
                bool drilled = false;
                bool drilledSomeDestructibleContent = false;
                MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref m_fakeCollisionSphere, voxelMapsFound, null);

                int drillInterval        = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.DRILL_INTERVAL_IN_MILISECONDS;
                int timerToDrillInterval = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.TIME_TO_DRILL_VOXEL_IN_MILISECONDS;

                foreach (MyVoxelMap voxelMap in voxelMapsFound)
                {
                    if ((collisionResult is MyVoxelMap) && ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrilled) > drillInterval) &&
                        (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds) > timerToDrillInterval)
                    {
                        drilled = true;
                        float          rangeStep          = 0;
                        float          radius             = GetRadiusNeededForTunel();
                        BoundingSphere bigSphereForTunnel = new BoundingSphere(m_fakeCollisionSphere.Center, radius);

                        while (rangeStep < m_range)
                        {
                            MyMwcVector3Int exactCenterOfDrilling = voxelMap.GetVoxelCoordinateFromMeters(bigSphereForTunnel.Center);

                            // we don't want to drill indestructible voxels or empty space
                            if (voxelMap.IsVoxelInVoxelMap(ref exactCenterOfDrilling) && voxelMap.GetVoxelMaterialIndestructibleContent(ref exactCenterOfDrilling) == MyVoxelConstants.VOXEL_CONTENT_FULL)
                            {
                                break;
                            }
                            else
                            {
                                drilledSomeDestructibleContent = true;
                            }

                            CutOutFromVoxel(voxelMap, ref bigSphereForTunnel);

                            bigSphereForTunnel.Center += 2 * WorldMatrix.Forward;

                            rangeStep += 1;
                        }
                    }
                }
                if (drilled)
                {
                    m_lastTimeDrilled = MyMinerGame.TotalGamePlayTimeInMilliseconds;
                    if (!drilledSomeDestructibleContent)
                    {
                        HUD.MyHud.ShowIndestructableAsteroidNotification();
                    }
                }
            }
        }