Пример #1
0
 private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal)
 {
     entity      = null;
     hitPosition = hitNormal = Vector3.Zero;
     VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()");
     m_intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignoreEntity, m_weapon, false, false, true, IntersectionFlags.ALL_TRIANGLES, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * CHECK_INTERSECTION_INTERVAL);
     VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
     if (m_intersection != null)
     {
         entity      = m_intersection.Value.Entity;
         hitPosition = m_intersection.Value.IntersectionPointInWorldSpace;
         hitNormal   = m_intersection.Value.NormalInWorldSpace;
     }
     if (entity == null)
     {
         var hitRigidBody = MyPhysics.CastRay(line.From, line.To, out hitPosition, out hitNormal);
         entity = hitRigidBody.GetEntity() as MyEntity;
     }
     if (entity == null)
     {
         return;
     }
     if (!(entity is MyCharacter))
     {
         entity = entity.GetTopMostParent();
     }
 }
Пример #2
0
        private static bool IsTargetVisible(MySmallShip smallShip, MyEntity otherEntity)
        {
            MyLine line = new MyLine(smallShip.WorldVolume.Center, otherEntity.GetPosition(), true);
            MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true);

            return(result != null && result.Value.Entity.GetBaseEntity() == otherEntity);
        }
Пример #3
0
        public void DrawLocationMarkers(MyHudLocationMarkers locationMarkers)
        {
            ProfilerShort.Begin("MyHudMarkerRender.DrawLocationMarkers");

            m_sortedMarkers.Clear();
            foreach (var entityMarker in locationMarkers.MarkerEntities)
            {
                m_sortedMarkers.Add(entityMarker.Value);
            }
            m_sortedMarkers.Sort(m_distanceComparer);

            foreach (var entityMarker in m_sortedMarkers)
            {
                MyEntity entity = entityMarker.Entity;
                if (entityMarker.ShouldDraw != null && !entityMarker.ShouldDraw())
                {
                    continue;
                }

                float distance = (float)(MySector.MainCamera.Position - entity.PositionComp.WorldVolume.Center).Length();
                if ((entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.NoOwnership ||
                     entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.FactionShare) && m_friendAntennaRange < distance)
                {
                    continue;
                }
                if ((entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Neutral ||
                     entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Enemies) && m_enemyAntennaRange < distance)
                {
                    continue;
                }
                if (entityMarker.TargetMode == MyRelationsBetweenPlayerAndBlock.Owner && m_ownerAntennaRange < distance)
                {
                    continue;
                }

                if (entityMarker.MustBeDirectlyVisible)
                {
                    LineD raycast = new LineD(MySector.MainCamera.Position, (Vector3)entity.PositionComp.WorldVolume.Center);
                    raycast.From += raycast.Direction;
                    var result = MyEntities.GetIntersectionWithLine(ref raycast, entity, MySession.ControlledEntity as MyEntity);
                    if (result.HasValue && !(result.Value.Entity == entity ||
                                             result.Value.Entity.Parent == entity ||
                                             result.Value.Entity == entity.Parent))
                    {
                        continue;
                    }
                }

                DrawLocationMarker(
                    GetStyleForRelation(entityMarker.TargetMode),
                    entity.LocationForHudMarker,
                    entityMarker,
                    0, 0);
            }

            m_hudScreen.DrawTexts();

            ProfilerShort.End();
        }
Пример #4
0
        public MyIntersectionResultLineTriangleEx?Intersect()
        {
            float  maxDist = 200;
            MyLine line    = new MyLine(MyCamera.Position, MyCamera.Position + MyCamera.ForwardVector * maxDist);
            var    result  = MyEntities.GetIntersectionWithLine(ref line, MySession.PlayerShip, null, true, true, false, false, true);

            return(result);
        }
        private void DebugDrawVertexNames()
        {
            //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(10, 0), "Voxel names searching", Color.Yellow, 0.5f);
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 500);

            VRage.Game.Models.MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.Static.LocalCharacter, null, false, true, true, VRage.Game.Components.IntersectionFlags.ALL_TRIANGLES, 0, false);


            if (intersection.HasValue)
            {
                if (intersection.Value.Entity is MyVoxelBase)
                {
                    MyVoxelBase voxels = intersection.Value.Entity as MyVoxelBase;
                    Vector3D    point  = intersection.Value.IntersectionPointInWorldSpace;
                    if (intersection.Value.Entity is MyPlanet)
                    {
                        VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: planet/moon", Color.Yellow, 0.5f);
                        VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Terrain: " + voxels.GetMaterialAt(ref point).ToString(), Color.Yellow, 0.5f);
                    }
                    else
                    {
                        VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: asteroid", Color.Yellow, 0.5f);
                        VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Terrain: " + voxels.GetMaterialAt(ref point).ToString(), Color.Yellow, 0.5f);
                    }
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 40), "Object size: " + voxels.SizeInMetres.ToString(), Color.Yellow, 0.5f);

                    //location

                    /*
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 50), "Location:", Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 60), "x " + Math.Round(point.X, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 70), "y " + Math.Round(point.Y, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 80), "z " + Math.Round(point.Z, 3).ToString(), Color.Yellow, 0.5f);*/
                }
                else if (intersection.Value.Entity is MyCubeGrid)
                {
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Detected grid object", Color.Yellow, 0.5f);
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), "Grid name: " + intersection.Value.Entity.DisplayName.ToString(), Color.Yellow, 0.5f);
                    int        row  = 4;
                    MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid;
                    VRage.Game.Models.MyIntersectionResultLineTriangleEx?t = null;
                    MySlimBlock block = null;
                    if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null)
                    {
                        DebugDrawModelTextures(block.FatBlock, ref row);
                    }
                }
                else
                {
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Unknown object detected", Color.Yellow, 0.5f);
                }
            }
            else
            {
                VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Nothing detected nearby", Color.Yellow, 0.5f);
            }
        }
Пример #6
0
        private static bool IsLookAtTarget(MySmallShip smallShip, MyEntity otherEntity)
        {
            if (!MUST_LOOK_AT_TARGET || MySession.Is25DSector)
            {
                return(true);
            }
            float  length = Vector3.Distance(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center);
            MyLine line   = new MyLine(smallShip.WorldVolume.Center, smallShip.WorldVolume.Center + smallShip.WorldMatrix.Forward * length * 1.5f, true);
            MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true);

            return(result != null && result.Value.Entity.GetBaseEntity() == otherEntity);
        }
Пример #7
0
        /// <summary>
        /// Check if the missile does not collide too close to ship
        /// after shooting and correct its starting position if it does.
        /// </summary>
        private Vector3 CorrectPosition(Vector3 position, Vector3 direction, MyEntity viewerEntity)
        {
            var predictedTrajectory = new MyLine(
                position - MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction,
                position + MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction,
                false);
            var intersection = MyEntities.GetIntersectionWithLine(ref predictedTrajectory, this, viewerEntity);

            if (intersection != null)
            {
                position = viewerEntity.GetPosition();
            }
            return(position);
        }
 private void UpdateTargetVisibility(MySmallShipBot bot)
 {
     if (locationVisibleCheckTimer <= 0)
     {
         MyLine line   = new MyLine(bot.GetPosition(), location, true);
         var    result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
         locationVisible           = !result.HasValue;
         locationVisibleCheckTimer = 0.25f;
     }
     else
     {
         locationVisibleCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
     }
 }
Пример #9
0
        private static void ComputeMaxDistance(MySunWindBillboardSmall billboard)
        {
            Vector3D vectord = -m_directionFromSunNormalized * 30000.0;
            LineD    line    = new LineD(((m_directionFromSunNormalized * 30000.0) + billboard.InitialAbsolutePosition) + vectord, billboard.InitialAbsolutePosition + (m_directionFromSunNormalized * 60000.0));
            MyIntersectionResultLineTriangleEx?nullable = MyEntities.GetIntersectionWithLine(ref line, null, null, false, true, true, IntersectionFlags.ALL_TRIANGLES, 0f, true);

            if (nullable != null)
            {
                billboard.MaxDistance = nullable.Value.Triangle.Distance - billboard.Radius;
            }
            else
            {
                billboard.MaxDistance = 60000f;
            }
        }
Пример #10
0
        private void UpdateTargetVisibility(MySmallShipBot bot)
        {
            if (m_target != null && m_visibilityCheckTimer <= 0)
            {
                Debug.Assert(!m_target.Closed);

                MyLine line   = new MyLine(bot.GetPosition(), m_target.GetPosition(), true);
                var    result = MyEntities.GetIntersectionWithLine(ref line, bot, m_target, true, ignoreChilds: true);
                m_targetVisible        = !result.HasValue;
                m_visibilityCheckTimer = 0.25f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
Пример #11
0
        public virtual void DrawLocationMarkers(MyHudLocationMarkers locationMarkers)
        {
            ProfilerShort.Begin("MyHudMarkerRender.DrawLocationMarkers");

            m_sortedMarkers.Clear();
            foreach (var entityMarker in locationMarkers.MarkerEntities)
            {
                if (entityMarker.Value.Entity.PositionComp == null) //to draw marker entity must have position
                {
                    continue;
                }
                m_sortedMarkers.Add(entityMarker.Value);
            }
            m_sortedMarkers.Sort(m_distanceComparer);

            foreach (var entityMarker in m_sortedMarkers)
            {
                MyEntity entity = entityMarker.Entity as MyEntity;
                if (entityMarker.ShouldDraw != null && !entityMarker.ShouldDraw())
                {
                    continue;
                }

                if (entityMarker.MustBeDirectlyVisible)
                {
                    LineD raycast = new LineD(MySector.MainCamera.Position, (Vector3)entity.PositionComp.WorldVolume.Center);
                    raycast.From += raycast.Direction;
                    var result = MyEntities.GetIntersectionWithLine(ref raycast, entity, MySession.Static.ControlledEntity as MyEntity);
                    if (result.HasValue && !(result.Value.Entity == entity ||
                                             result.Value.Entity.Parent == entity ||
                                             result.Value.Entity == entity.Parent))
                    {
                        continue;
                    }
                }

                DrawLocationMarker(
                    GetStyleForRelation(entityMarker.TargetMode),
                    entity.LocationForHudMarker,
                    entityMarker,
                    0, 0);
            }

            m_hudScreen.DrawTexts();

            ProfilerShort.End();
        }
Пример #12
0
        /// <summary>
        /// Chceck if ship can see target
        /// </summary>
        /// <param name="position">Target position</param>
        /// <param name="target">Target entity.</param>
        /// <returns>True, if bot can see position.</returns>
        public static MyEntity CanSee(MyEntity source, Vector3 position, MyEntity ignoreEntity)
        {
            MyIntersectionResultLineTriangleEx?result = null;

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MySmallShip CanSee");
            //There is 100 multiplier because Epsilon can get lost during transformation inside GetAllIntersectionWithLine
            //and normalization assert then appears
            if ((source.GetPosition() - position).Length() > MyMwcMathConstants.EPSILON * 100.0f)
            {
                var line = new MyLine(source.GetPosition(), position, true);
                result = MyEntities.GetIntersectionWithLine(ref line, source, ignoreEntity, ignoreChilds: true);
            }

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

            return(result.HasValue ? result.Value.Entity : null);
        }
Пример #13
0
        private static void ComputeMaxDistance(MySunWindBillboardSmall billboard)
        {
            Vector3 sunWindVector = m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF;
            var     offset        = (-m_directionFromSunNormalized * MySunWindConstants.RAY_CAST_DISTANCE);
            //  This line start where billboard starts and end at place that is farest possible place billboard can reach
            //  If intersection found, we will mark that place as small billboard's destination. It can't go further.
            LineD line = new LineD((sunWindVector + billboard.InitialAbsolutePosition) + offset, billboard.InitialAbsolutePosition + m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_TOTAL);
            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, null, null);

            if (intersection != null)
            {
                billboard.MaxDistance = (float)(intersection.Value.Triangle.Distance - billboard.Radius);
            }
            else
            {
                billboard.MaxDistance = MySunWindConstants.SUN_WIND_LENGTH_TOTAL;
            }
        }
Пример #14
0
        public void DoWork()
        {
            try
            {
                MyEntities.EntityCloseLock.AcquireShared();

                if (m_bot == null)
                {
                    return;
                }

                BoundingSphere boundingSphere = new BoundingSphere(m_position, m_bot.WorldVolume.Radius * 2.0f);
                if (MyEntities.GetIntersectionWithSphere(ref boundingSphere) != null)
                {
                    return;
                }

                Matrix transform            = Matrix.CreateWorld(m_position, MyMwcUtils.Normalize(m_targetPosition - m_position), m_up);
                float  distanceToRoutePoint = Vector3.Dot(m_targetPosition - m_position, transform.Forward);

                for (int i = 0; i < m_points.Length; i++)
                {
                    Vector3 transformedPoint = Vector3.Transform(m_points[i], transform);
                    MyLine  line             = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true);

                    var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, null, true);
                    if (result.HasValue)
                    {
                        // Collision detected
                        return;
                    }
                }

                Result = m_position;
            }
            finally
            {
                if (m_bot != null)
                {
                    m_bot.OnClose -= m_bot_OnClose;
                }
                MyEntities.EntityCloseLock.ReleaseShared();
            }
        }
Пример #15
0
        private void DebugDrawGeneratingBlock()
        {
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200);
            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.LocalCharacter, null);

            if (intersection.HasValue && intersection.Value.Entity is MyCubeGrid)
            {
                MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid;
                MyIntersectionResultLineTriangleEx?t = null;
                MySlimBlock block = null;
                if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null)
                {
                    if (block.BlockDefinition.IsGeneratedBlock)
                    {
                        DebugDrawGeneratingBlock(block);
                    }
                }
            }
        }
Пример #16
0
        private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal, out bool hitHead)
        {
            entity      = null;
            hitPosition = hitNormal = Vector3.Zero;
            hitHead     = false;

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()");
            m_intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignoreEntity, m_weapon, false, false, true, IntersectionFlags.ALL_TRIANGLES, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * CHECK_INTERSECTION_INTERVAL);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (m_intersection != null)
            {
                entity      = m_intersection.Value.Entity;
                hitPosition = m_intersection.Value.IntersectionPointInWorldSpace;
                hitNormal   = m_intersection.Value.NormalInWorldSpace;
            }
            if (entity == null)
            {
                var hitInfo = MyPhysics.CastRay(line.From, line.To);
                if (hitInfo.HasValue)
                {
                    entity      = hitInfo.Value.HkHitInfo.GetHitEntity() as MyEntity;
                    hitPosition = hitInfo.Value.Position;
                    hitNormal   = hitInfo.Value.HkHitInfo.Normal;
                }
            }
            if (entity == null)
            {
                return;
            }

            if (m_projectileAmmoDefinition.HeadShot && entity is MyCharacter)
            {
                MyCharacter hitCharacter = entity as MyCharacter;
                MyIntersectionResultLineTriangleEx?t;
                hitCharacter.GetIntersectionWithLine(ref line, out t, out hitHead);
            }

            if (!(entity is MyCharacter))
            {
                entity = entity.GetTopMostParent();
            }
        }
Пример #17
0
        /// <summary>
        /// GetIntersectedEntity
        /// </summary>
        /// <returns></returns>
        private MyEntity GetIntersectedEntity()
        {
            MyLine   mouseSelectionLine = MyUtils.ConvertMouseToLine();
            var      result             = MyEntities.GetIntersectionWithLine(ref mouseSelectionLine, null, null);
            MyEntity entity             = result.HasValue ? result.Value.Entity : null;

            if (entity is MyLargeShipGunBase)
            {
                entity = ((MyLargeShipGunBase)entity).PrefabParent;
            }

            if (m_bEnableAABBUnderMouse)
            {
                m_physOverlapElemList.Clear();
                MyEntities.GetIntersectedElements(ref mouseSelectionLine, m_physOverlapElemList);
            }

            return(entity);
        }
Пример #18
0
        private static bool IsCustomLookAtTarget(MySmallShip smallShip, MyEntity otherEntity, float radius)
        {
            if (!MUST_LOOK_AT_TARGET)
            {
                return(true);
            }

            BoundingSphere sphere          = new BoundingSphere(otherEntity.WorldVolume.Center, radius);
            Ray            ray             = new Ray(smallShip.GetPosition(), smallShip.WorldMatrix.Forward);
            float?         rayIntersection = ray.Intersects(sphere);

            if (rayIntersection.HasValue)
            {
                MyLine line = new MyLine(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center, true);
                MyIntersectionResultLineTriangleEx?result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true);
                return(!result.HasValue || !result.HasValue || result.Value.Entity == otherEntity);
            }
            return(false);
        }
Пример #19
0
        private void DebugDrawModelTextures()
        {
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200);
            MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, MySession.LocalCharacter, null);

            if (intersection.HasValue)
            {
                int row = 0;

                if (intersection.Value.Entity is MyCubeGrid)
                {
                    MyCubeGrid grid = intersection.Value.Entity as MyCubeGrid;
                    MyIntersectionResultLineTriangleEx?t = null;
                    MySlimBlock block = null;
                    if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null)
                    {
                        DebugDrawModelTextures(block.FatBlock, ref row);
                    }
                }
            }
        }
Пример #20
0
        private void UpdateVisibility(MySmallShipBot bot, Vector3 targetPosition)
        {
            if (m_visibilityCheckTimer <= 0)
            {
                if (bot.GetPosition() == targetPosition)
                {
                    m_targetVisible = true;
                }
                else
                {
                    MyLine line   = new MyLine(bot.GetPosition(), targetPosition, true);
                    var    result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true);
                    m_targetVisible = !result.HasValue;
                }

                m_visibilityCheckTimer = 0.5f;
            }
            else
            {
                m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
            }
        }
        void AssignBotTargets()
        {
            MyEntity transporterShip = MyScriptWrapper.TryGetEntity((uint)EntityID.TransporterShip);

            if (transporterShip != null)
            {
                for (int i = m_attackerBots.Count - 1; i >= 0; i--)
                {
                    var bot = m_attackerBots[i];

                    MyLine line   = new MyLine(bot.GetPosition(), transporterShip.GetPosition(), true);
                    var    result = MyEntities.GetIntersectionWithLine(ref line, bot, transporterShip, true, ignoreChilds: true);
                    if (!result.HasValue)
                    {
                        bot.Attack(transporterShip);
                        bot.SpeedModifier = 0;
                        m_attackerWaitingForPass.Add(bot);

                        m_attackerBots.RemoveAt(i);
                    }
                }
            }
        }
Пример #22
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);
        }
Пример #23
0
        internal override void Update(MySmallShipBot bot)
        {
            base.Update(bot);

            if (bot.Leader != null)
            {
                if (ShouldFallAsleep(bot))
                {
                    bot.IsSleeping = true;
                    return;
                }

                Vector3 leaderToBot             = bot.GetPosition() - bot.Leader.GetPosition();
                Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot);
                Vector3 botToFormationPosition  = formationPositionActual - bot.GetPosition();

                float leaderDistance            = leaderToBot.Length();
                float formationPositionDistance = botToFormationPosition.Length();

                Vector3 flyTo;
                if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON)
                {
                    float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20;
                    flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance;
                    flyTo = MyMwcUtils.Normalize(flyTo);
                    flyTo = bot.GetPosition() + flyTo * formationPositionDistance;

                    // Update leader visibility
                    if (visibilityCheckTimer <= 0)
                    {
                        MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true);
                        leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue;

                        visibilityCheckTimer = 0.5f;
                    }
                    else
                    {
                        visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                    }
                }
                else
                {
                    // Bot is on formation position
                    flyTo         = bot.GetPosition() + bot.WorldMatrix.Forward;
                    leaderVisible = true;
                }

                if (leaderVisible)
                {
                    bool    afterburner = /*bot.Leader.IsAfterburnerOn() || */ formationPositionDistance > AFTERBURNER_DISTANCE;
                    Vector3 lookTarget  = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual;

                    float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f);

                    factor = factor * factor * factor;

                    bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true);

                    checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;

                    findSmallship.Init(bot);
                }
                else
                {
                    if (leaderDistance > MIN_LEADER_DISTANCE)
                    {
                        findSmallship.Update(bot, bot.Leader);

                        if (findSmallship.PathNotFound)
                        {
                            //We dont want our friends sleeping elsewhere
                            //  bot.IsSleeping = true;
                        }
                    }
                }
            }
        }
Пример #24
0
        public void RequestJump(string destinationName, Vector3D destination, long userId)
        {
            if (!Vector3.IsZero(MyGravityProviderSystem.CalculateNaturalGravityInPoint(m_grid.WorldMatrix.Translation)))
            {
                var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpFromGravity, 1500);
                MyHud.Notifications.Add(notification);
                return;
            }
            if (!Vector3.IsZero(MyGravityProviderSystem.CalculateNaturalGravityInPoint(destination)))
            {
                var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpIntoGravity, 1500);
                MyHud.Notifications.Add(notification);
                return;
            }

            if (!IsJumpValid(userId))
            {
                return;
            }

            if (MySession.Static.Settings.WorldSizeKm > 0 && destination.Length() > MySession.Static.Settings.WorldSizeKm * 500)
            {
                var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpOutsideWorld, 1500);
                MyHud.Notifications.Add(notification);
                return;
            }

            m_selectedDestination = destination;
            double maxJumpDistance = GetMaxJumpDistance(userId);

            m_jumpDirection = destination - m_grid.WorldMatrix.Translation;
            double jumpDistance   = m_jumpDirection.Length();
            double actualDistance = jumpDistance;

            if (jumpDistance > maxJumpDistance)
            {
                double ratio = maxJumpDistance / jumpDistance;
                actualDistance   = maxJumpDistance;
                m_jumpDirection *= ratio;
            }

            //By Gregory: Check for obstacle not that fast but happens rarely(on Jump drive enable)
            //TODO: make compatible with GetMaxJumpDistance and refactor to much code checks for actual jump
            var direction = Vector3D.Normalize(destination - m_grid.WorldMatrix.Translation);
            var startPos  = m_grid.WorldMatrix.Translation + m_grid.PositionComp.LocalAABB.Extents.Max() * direction;
            var line      = new LineD(startPos, destination);


            var intersection = MyEntities.GetIntersectionWithLine(ref line, m_grid, null, ignoreObjectsWithoutPhysics: false);

            Vector3D newDestination = Vector3D.Zero;
            Vector3D newDirection   = Vector3D.Zero;

            if (intersection.HasValue)
            {
                MyEntity MyEntity = intersection.Value.Entity as MyEntity;

                var targetPos     = MyEntity.WorldMatrix.Translation;
                var obstaclePoint = MyUtils.GetClosestPointOnLine(ref startPos, ref destination, ref targetPos);

                MyPlanet MyEntityPlanet = intersection.Value.Entity as MyPlanet;
                if (MyEntityPlanet != null)
                {
                    var notification = new MyHudNotification(MySpaceTexts.NotificationCannotJumpIntoGravity, 1500);
                    MyHud.Notifications.Add(notification);
                    return;
                }

                //var Radius = MyEntityPlanet != null ? MyEntityPlanet.MaximumRadius : MyEntity.PositionComp.LocalAABB.Extents.Length();
                var Radius = MyEntity.PositionComp.LocalAABB.Extents.Length();

                destination           = obstaclePoint - direction * (Radius + m_grid.PositionComp.LocalAABB.HalfExtents.Length());
                m_selectedDestination = destination;
                m_jumpDirection       = m_selectedDestination - startPos;
                actualDistance        = m_jumpDirection.Length();
            }

            if (actualDistance < MIN_JUMP_DISTANCE)
            {
                MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                           buttonType: MyMessageBoxButtonsType.OK,
                                           messageText: GetWarningText(actualDistance, intersection.HasValue),
                                           messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionWarning)
                                           ));
            }
            else
            {
                MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                           buttonType : MyMessageBoxButtonsType.YES_NO,
                                           messageText : GetConfimationText(destinationName, jumpDistance, actualDistance, userId, intersection.HasValue),
                                           messageCaption : MyTexts.Get(MyCommonTexts.MessageBoxCaptionPleaseConfirm),
                                           size : new Vector2(0.839375f, 0.3675f), callback : delegate(MyGuiScreenMessageBox.ResultEnum result)
                {
                    if (result == MyGuiScreenMessageBox.ResultEnum.YES && IsJumpValid(userId))
                    {
                        RequestJump(m_selectedDestination, userId);
                    }
                    else
                    {
                        AbortJump();
                    }
                }
                                           ));
            }
        }
Пример #25
0
        private void DebugDrawVertexNames()
        {
            //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(10, 0), "Voxel names searching", Color.Yellow, 0.5f);
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 500);
            MyIntersectionResultLineTriangleEx?intersection =
                MyEntities.GetIntersectionWithLine(ref line, MySession.Static.LocalCharacter, null, false, true, true,
                                                   VRage.Game.Components.IntersectionFlags.ALL_TRIANGLES, 0, false);

            float yPos = 20;

            if (intersection.HasValue)
            {
                if (intersection.Value.Entity is MyVoxelBase)
                {
                    MyVoxelBase voxels = (MyVoxelBase)intersection.Value.Entity;
                    Vector3D    point  = intersection.Value.IntersectionPointInWorldSpace;
                    if (intersection.Value.Entity is MyPlanet)
                    {
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Type: planet/moon", Color.Yellow,
                                                      DEBUG_SCALE); yPos += 10;
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos),
                                                      "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE); yPos += 10;
                    }
                    else
                    {
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Type: asteroid", Color.Yellow,
                                                      DEBUG_SCALE); yPos += 10;
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos),
                                                      "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE); yPos += 10;
                    }
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos),
                                                  "Object size: " + voxels.SizeInMetres, Color.Yellow, DEBUG_SCALE); yPos += 10;

                    //location

                    /*
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 50), "Location:", Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 60), "x " + Math.Round(point.X, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 70), "y " + Math.Round(point.Y, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 80), "z " + Math.Round(point.Z, 3).ToString(), Color.Yellow, 0.5f);*/
                }
                else if (intersection.Value.Entity is MyCubeGrid)
                {
                    MyCubeGrid grid = (MyCubeGrid)intersection.Value.Entity;
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Detected grid object", Color.Yellow, DEBUG_SCALE); yPos += 10;
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), String.Format("Grid name: {0}", grid.DisplayName), Color.Yellow,
                                                  DEBUG_SCALE); yPos += 10;

                    MyIntersectionResultLineTriangleEx?t;
                    MySlimBlock block;
                    if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null)
                    {
                        if (block.FatBlock != null)
                        {
                            DebugDrawModelTextures(block.FatBlock, ref yPos);
                        }
                        else
                        {
                            DebugDrawBareBlockInfo(block, ref yPos);
                        }
                    }
                }
                else
                {
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Unknown object detected @ distance " + intersection.Value.Triangle.Distance + "m", Color.Yellow,
                                                  DEBUG_SCALE); yPos += 10;
                }
                MyRenderProxy.DebugDrawText2D(new Vector2(20, yPos), "Distance " + intersection.Value.Triangle.Distance + "m", Color.Yellow,
                                              DEBUG_SCALE);
            }
            else
            {
                MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Nothing detected nearby", Color.Yellow, DEBUG_SCALE);
            }
        }
Пример #26
0
        public void DoWork()
        {
            try
            {
                MyEntities.EntityCloseLock.AcquireShared();

                if (m_entity == null)
                {
                    return;
                }

                //if (m_entity.EntityId.HasValue && m_entity.EntityId.Value.NumericValue == 119150)
                // {
                //  }

                //  if (m_entity == MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip)
                //  {
                //  }

                Vector3 directionToSunNormalized = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized();

                VisibleFromSun = false;

                MyLine line2   = new MyLine(m_entity.WorldAABB.GetCenter(), m_entity.WorldAABB.GetCenter() + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true);
                var    result2 = MyEntities.GetIntersectionWithLine(ref line2, m_entity, null, true, true, true);
                VisibleFromSun |= IsVisibleFromSun(result2);

                if (m_entity.RenderObjects != null && m_entity.RenderObjects[0].FastCastShadowResolve)
                {
                    return;
                }

                Vector3[] corners = new Vector3[8];
                m_entity.LocalAABB.GetCorners(corners);
                for (int i = 0; i < 8; i++)
                {
                    corners[i] = Vector3.Transform(corners[i], m_entity.WorldMatrix);
                }

                for (int i = 0; i < 8; i++)
                {
                    MyLine line   = new MyLine(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true);
                    var    result = MyEntities.GetIntersectionWithLine(ref line, m_entity, null, true, true, true);

                    VisibleFromSun |= IsVisibleFromSun(result);

                    if (VisibleFromSun)
                    {
                        break;
                    }
                }
            }
            finally
            {
                if (m_entity != null)
                {
                    m_entity.OnClose -= m_entity_OnMarkForClose;
                }

                MyEntities.EntityCloseLock.ReleaseShared();
            }
        }
        protected override void DoDetection(bool useHead)
        {
            ProfilerShort.Begin("DoDetection");
            if (Character == MySession.Static.ControlledEntity)
            {
                MyHud.SelectedObjectHighlight.RemoveHighlight();
            }

            var head    = Character.GetHeadMatrix(false);
            var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head)

            Vector3D from;
            Vector3D dir;

            if (!useHead)
            {
                //Ondrej version
                var cameraMatrix = MySector.MainCamera.WorldMatrix;
                dir  = cameraMatrix.Forward;
                from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir);
            }
            else
            {
                //Petr version
                dir  = head.Forward;
                from = headPos;
            }

            Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE;

            StartPosition = from;
            LineD intersectionLine = new LineD(from, to);

            // Processing of hit entities
            var  geometryHit  = MyEntities.GetIntersectionWithLine(ref intersectionLine, null, null, ignoreFloatingObjects: false);
            bool hasUseObject = false;

            if (geometryHit.HasValue)
            {
                var hitEntity = geometryHit.Value.Entity;

                // Cube Grids are special case
                var cubeGrid = hitEntity as MyCubeGrid;
                if (cubeGrid != null)
                {
                    // For hit cube grids get the fat hit fatblock instead.
                    var slimBlock = cubeGrid.GetTargetedBlock(geometryHit.Value.IntersectionPointInWorldSpace);
                    if (slimBlock != null && slimBlock.FatBlock != null)
                    {
                        hitEntity = slimBlock.FatBlock;
                    }
                }

                m_hitUseComponents.Clear();
                var hitUseObject = hitEntity as IMyUseObject;
                // Retrive all above use components from parent structure. (Because of subParts)
                GetUseComponentsFromParentStructure(hitEntity, m_hitUseComponents);
                // Check for UseObjects and entities with UseObjectComponentBase.
                // Assuming that entity cannot be IMyUseObject and have UseObjectComponentBase in hierarchy
                // at the same time.
                if (hitUseObject != null || m_hitUseComponents.Count > 0)
                {
                    if (m_hitUseComponents.Count > 0)
                    {
                        // Process the valid hit entity
                        var    closestDetectorDistance       = float.MaxValue;
                        double physicalHitDistance           = Vector3D.Distance(from, geometryHit.Value.IntersectionPointInWorldSpace);
                        MyUseObjectsComponentBase hitUseComp = null;
                        // Evaluate the set of found detectors and try to find the closest one
                        foreach (var hitUseComponent in m_hitUseComponents)
                        {
                            float detectorDistance;
                            var   interactive = hitUseComponent.RaycastDetectors(from, to, out detectorDistance);
                            detectorDistance *= MyConstants.DEFAULT_INTERACTIVE_DISTANCE;
                            if (Math.Abs(detectorDistance) < Math.Abs(closestDetectorDistance) &&
                                (detectorDistance < physicalHitDistance)) // Remove to fix the problem with picking through physic bodies,
                            {                                             // but will introduce new problem with detectors inside physic bodies.
                                closestDetectorDistance = detectorDistance;
                                hitUseComp   = hitUseComponent;
                                hitEntity    = hitUseComponent.Entity;
                                hitUseObject = interactive;
                            }
                        }

                        // Detector found
                        if (hitUseComp != null)
                        {
                            // Process successful hit with results
                            var detectorPhysics = hitUseComp.DetectorPhysics;
                            HitMaterial    = detectorPhysics.GetMaterialAt(HitPosition);
                            HitBody        = geometryHit.Value.Entity.Physics.RigidBody;
                            HitPosition    = geometryHit.Value.IntersectionPointInWorldSpace;
                            DetectedEntity = hitEntity;
                        }
                    }
                    else
                    {
                        // Case for hitting IMyUseObject already before even looking for UseComponent.
                        // Floating object case.
                        HitMaterial = hitEntity.Physics.GetMaterialAt(HitPosition);
                        HitBody     = hitEntity.Physics.RigidBody;
                    }

                    // General logic for processing both cases.
                    if (hitUseObject != null)
                    {
                        HitPosition    = geometryHit.Value.IntersectionPointInWorldSpace;
                        DetectedEntity = hitEntity;

                        if (UseObject != null && UseObject != hitEntity && UseObject != hitUseObject)
                        {
                            UseObject.OnSelectionLost();
                        }

                        if (Character == MySession.Static.ControlledEntity && hitUseObject.SupportedActions != UseActionEnum.None)
                        {
                            HandleInteractiveObject(hitUseObject);

                            UseObject    = hitUseObject;
                            hasUseObject = true;
                        }
                    }
                }
            }

            if (!hasUseObject)
            {
                if (UseObject != null)
                {
                    UseObject.OnSelectionLost();
                }

                UseObject = null;
            }

            ProfilerShort.End();
        }
Пример #28
0
        public void DoWork()
        {
            //  Search for target to attack
            ClosestEnemy  = null;
            ClosestVisual = null;

            float distanceSqr              = m_seeDistance * m_seeDistance;
            float closestEnemyDistanceSqr  = float.PositiveInfinity;
            float closestVisualDistanceSqr = float.PositiveInfinity;

            using (var rbFounded = PoolList <MyRBElement> .Get())
            {
                try
                {
                    MyEntities.EntityCloseLock.AcquireShared();

                    MyDynamicAABBTree prunningStructure = MyPhysics.physicsSystem.GetRigidBodyModule().GetPruningStructure();

                    BoundingBox rbInputElementGetWorldSpaceAABB = new BoundingBox(
                        m_botWorldMatrix.Translation - new Vector3(m_seeDistance),
                        m_botWorldMatrix.Translation + new Vector3(m_seeDistance));
                    prunningStructure.OverlapAllBoundingBox(ref rbInputElementGetWorldSpaceAABB, rbFounded, (uint)MyElementFlag.EF_RB_ELEMENT);

                    //now try find spot
                    foreach (MyRBElement rb in rbFounded)
                    {
                        if (m_bot == null)
                        {
                            return;
                        }

                        var rigidBody = rb.GetRigidBody();
                        if (rigidBody == null)
                        {
                            continue;
                        }

                        MyEntity entity = ((MyPhysicsBody)rigidBody.m_UserData).Entity;
                        if (entity == m_bot || entity == null || entity.AIPriority == -1)
                        {
                            continue;
                        }


                        entity = entity.GetBaseEntity();    // Large weapons

                        // Ignore spoiled holograms
                        if (m_bot.IsSpoiledHologram(entity))
                        {
                            continue;
                        }

                        // Don't attack disabled weapons
                        MyPrefabLargeWeapon largeWeapon = entity as MyPrefabLargeWeapon;
                        MySmallShip         smallShip   = entity as MySmallShip;
                        MyPrefabLargeShip   largeShip   = entity as MyPrefabLargeShip;

                        if (largeWeapon != null && !largeWeapon.IsWorking())
                        {
                            continue;
                        }

                        // Test smallships and largeweapons
                        if (smallShip != null || largeWeapon != null || largeShip != null)
                        {
                            // Is enemy?
                            if (MyFactions.GetFactionsRelation(m_bot, entity) == MyFactionRelationEnum.Enemy && CanSeeTarget(m_bot, entity))
                            {
                                var entityDistanceSqr = Vector3.DistanceSquared(entity.GetPosition(), m_position);

                                if (entityDistanceSqr < distanceSqr &&
                                    (ClosestEnemy == null || entity.AIPriority >= ClosestEnemy.AIPriority) &&
                                    (entityDistanceSqr < closestEnemyDistanceSqr || entity.AIPriority > ClosestEnemy.AIPriority))
                                {
                                    MyLine line   = new MyLine(m_position, entity.GetPosition(), true);
                                    var    result = MyEntities.GetIntersectionWithLine(ref line, m_bot, entity, true, ignoreChilds: true);
                                    if (!result.HasValue)
                                    {
                                        // Visual Detection - ignore visualy detected targets if they are further than any normaly detected target
                                        if (IsVisualyDetected(smallShip))
                                        {
                                            if (entityDistanceSqr < closestVisualDistanceSqr)
                                            {
                                                ClosestVisual            = entity;
                                                closestVisualDistanceSqr = entityDistanceSqr;
                                            }
                                        }
                                        else
                                        {
                                            closestEnemyDistanceSqr = entityDistanceSqr;
                                            ClosestEnemy            = entity;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    MyEntities.EntityCloseLock.ReleaseShared();
                }
            }
        }
Пример #29
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();
        }
Пример #30
0
        /// <summary>
        /// Updates resource.
        /// </summary>
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();

            if ((!GetParentMinerShip().Config.Engine.On || GetParentMinerShip().Fuel <= 0) &&
                (CurrentState == MyHarvestingDeviceEnum.InVoxel || CurrentState == MyHarvestingDeviceEnum.FindingVoxel))
            {
                StartFastReturningBack();
            }

            if (CurrentState == MyHarvestingDeviceEnum.InsideShip)
            {
                //  Do nothing
                return;
            }

            if (CurrentState == MyHarvestingDeviceEnum.FindingVoxel)
            {
                //  Head in local space
                m_headPositionLocal += this.LocalMatrix.Forward * MyHarvestingTubeConstants.EJECTION_SPEED_IN_METERS_PER_SECOND;
            }
            else if (CurrentState == MyHarvestingDeviceEnum.ReturningBack)
            {
                //  Head in local space
                m_headPositionLocal -= this.LocalMatrix.Forward * MyHarvestingTubeConstants.EJECTION_SPEED_IN_METERS_PER_SECOND;
            }
            else if (CurrentState == MyHarvestingDeviceEnum.FastReturningBack)
            {
                //  Head in local space
                m_headPositionLocal -= this.LocalMatrix.Forward * MyHarvestingTubeConstants.FAST_PULL_BACK_IN_METERS_PER_SECOND;
            }

            //  Transform head position into world space
            Matrix worldMatrix = Parent.WorldMatrix;

            m_harvestingOreHead.LocalMatrix = Matrix.CreateWorld(m_headPositionLocal, m_harvestingOreHead.LocalMatrix.Forward, m_harvestingOreHead.LocalMatrix.Up);
            m_headPositionTransformed       = m_harvestingOreHead.WorldMatrix.Translation;

            //  Distance must carry sign (plus/minus) because when we need to know if head is behind it's starting point when pulling back
            //  IMPORTANT: Forward is in -Z direction, so that's why I subtract position from head and not oppositely

            float distance = this.LocalMatrix.Translation.Z - m_headPositionLocal.Z;

            if (CurrentState == MyHarvestingDeviceEnum.ReturningBack ||
                CurrentState == MyHarvestingDeviceEnum.FastReturningBack)
            {
                if (distance <= MyHarvestingTubeConstants.DISTANCE_TO_PLUG_IN_THE_TUBE)
                {
                    StartInsideShip();
                }
            }
            else
            {
                if (distance >= MyHarvestingTubeConstants.MAX_DISTANCE_OF_HARVESTING_DEVICE)
                {
                    StartReturningBack();
                }
            }

            //  Sphere for head of harvester
            BoundingSphere headSphere = new BoundingSphere(m_headPositionTransformed, m_harvestingOreHead.ModelLod0.BoundingSphere.Radius);

            if (CurrentState == MyHarvestingDeviceEnum.FindingVoxel)
            {
                //  Check if head doesn't collide with anything
                MyEntity sphereResult = MyEntities.GetIntersectionWithSphere(ref headSphere, m_parentMinerShip, null);
                if (sphereResult != null)
                {
                    if (sphereResult is MyVoxelMap)
                    {
                        StartInVoxel((MyVoxelMap)sphereResult);
                    }
                    else
                    {
                        //  Intersection between sphere and anything else but voxels, so we start pulling back quickly
                        StartFastReturningBack();
                    }
                }
            }

            //  If we are connected to voxel check permanently if the voxel is still there
            if ((CurrentState == MyHarvestingDeviceEnum.InVoxel) && (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeCheckedForVoxelPresence) > MyHarvestingTubeConstants.INTERVAL_TO_CHECK_FOR_VOXEL_CONNECTION_IN_MILISECONDS)
            {
                m_lastTimeCheckedForVoxelPresence = MyMinerGame.TotalGamePlayTimeInMilliseconds;
                //  Check if head doesn't collide with anything
                MyEntity sphereResult = MyEntities.GetIntersectionWithSphere(ref headSphere, m_parentMinerShip, null);
                if (!(sphereResult is MyVoxelMap))
                {
                    StartFastReturningBack();
                }
            }

            //  If we are connected to voxel we can harvest it
            if (CurrentState == MyHarvestingDeviceEnum.InVoxel)
            {
                m_actualVoxelContent -= m_harvestingSpeed;

                if (m_actualVoxelContent <= 0)
                {
                    StartReleaseVoxel();
                }
            }

            if ((WorldMatrix.Translation - m_headPositionTransformed).Length() > MyMwcMathConstants.EPSILON)
            {
                //  Check if tube doesn't colide with something
                MyLine tubeLine = new MyLine(WorldMatrix.Translation, m_headPositionTransformed, true);
                MyIntersectionResultLineTriangleEx?tubeIntersection = MyEntities.GetIntersectionWithLine(ref tubeLine, this, m_parentMinerShip);

                //  We colide with something and we need fast return back
                if (tubeIntersection != null)
                {
                    StartFastReturningBack();
                }
            }

            if (CurrentState == MyHarvestingDeviceEnum.InVoxel)
            {
                m_parentMinerShip.IncreaseHeadShake(MyHarvestingTubeConstants.SHAKE_DURING_IN_VOXELS);
            }
            else if ((CurrentState == MyHarvestingDeviceEnum.FastReturningBack) ||
                     (CurrentState == MyHarvestingDeviceEnum.FindingVoxel) ||
                     (CurrentState == MyHarvestingDeviceEnum.ReturningBack))
            {
                m_parentMinerShip.IncreaseHeadShake(MyHarvestingTubeConstants.SHAKE_DURING_EJECTION);
            }

            if (m_light != null)
            {
                m_light.SetPosition(m_headPositionTransformed - WorldMatrix.Forward);
            }

            if ((m_tubeMovingCue != null) && (m_tubeMovingCue.Value.IsPlaying == true))
            {
                MyAudio.UpdateCuePosition(m_tubeMovingCue, WorldMatrix.Translation,
                                          WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity);
            }

            if ((m_grindingCue != null) && (m_grindingCue.Value.IsPlaying == true))
            {
                MyAudio.UpdateCuePosition(m_grindingCue, m_headPositionTransformed,
                                          WorldMatrix.Forward, WorldMatrix.Up, Parent.Physics.LinearVelocity);
            }

            m_harvestingOreHead.SetData(ref m_worldMatrixForRenderingFromCockpitView);
        }