예제 #1
0
            /// <summary>
            /// Advance routefinding.
            /// </summary>
            /// <returns>True when routefinding is finished.</returns>
            public bool AdvanceRoutefinding(out Vector3?result)
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("AdvanceRoutefinding");

                using (MyEntities.EntityCloseLock.AcquireSharedUsing())
                {
                    if (Bot == null)
                    {
                        result = null;
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                        return(true);
                    }  // bot was closed, no need to continue

                    using (PositionMemory.RouteMemoryLock.AcquireSharedUsing())
                    {
                        for (int pointsTested = 0; pointsTested < MAX_POINTS_TESTED_PER_ROUTE_UPDATE; PositionMemoryIndex--, pointsTested++)
                        {
                            if (PositionMemoryIndex == -1)
                            {
                                result = null;
                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                                return(true);
                            }  // all points done, no route found

                            Vector3 routePosition        = PositionMemory.GetItem(PositionMemoryIndex);
                            Matrix  transform            = Matrix.CreateWorld(Position, MyMwcUtils.Normalize(routePosition - Position), Up);
                            float   distanceToRoutePoint = Vector3.Dot(routePosition - Position, transform.Forward);

                            if ((routePosition - Position).LengthSquared() < 5 * 5)
                            {
                                continue;                                                      // too close for comfort, try next point
                            }
                            bool collisionFound = false;
                            for (int i = 0; i < Points.Length; i++)
                            {
                                Vector3 transformedPoint   = Vector3.Transform(Points[i], transform);
                                MyLine  line               = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true);
                                var     intersectionResult = MyEntities.GetAnyIntersectionWithLine(ref line, Bot, null, true, false, true, true);
                                if (intersectionResult.HasValue)
                                {
                                    collisionFound = true;  // collision: try next point
                                    break;
                                }
                            }
                            if (!collisionFound)
                            {
                                result = routePosition;
                                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                                return(true);
                            }
                        }
                    }
                }

                result = null;

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                return(false);
            }
예제 #2
0
        private bool IsPossibleTarget(MySmallShip smallShip, params object[] args)
        {
            if (!IsPotentialTarget(smallShip, args))
            {
                return(false);
            }

            MyLine  testRay = new MyLine(m_gun.GetBarell().GetPosition(), smallShip.GetPosition(), false);
            Vector3?result  = MyEntities.GetAnyIntersectionWithLine(ref testRay, this, smallShip, true, true, false, true);

            //smallShip.GetIntersectionWithLine(ref testRay, out result);
            return(result == null);
        }
예제 #3
0
        // Return whether a waypoint is visible from the current position. Ignores debris, ammo and ships.
        // You can provide a cache that contains previous query results for this position. Results of new queries will be added to the cache.
        public bool IsVisibleFrom(Vector3 position, MyEntity ignore = null, Dictionary <MyWayPoint, bool> visibilityCache = null)
        {
            bool visible;

            if (visibilityCache == null || !visibilityCache.TryGetValue(this, out visible))
            {
                if (Vector3.DistanceSquared(position, Position) < 0.01f)
                {
                    visible = true;
                }
                else
                {
                    var line = new MyLine(position, Position, true);
                    visible = (MyEntities.GetAnyIntersectionWithLine(ref line, ignore, null, true, true, true, false) == null);  // skip explosion debris, ammo, ships, closed doors that can open, dummies
                }

                if (visibilityCache != null)
                {
                    visibilityCache[this] = visible;
                }
            }
            return(visible);
        }
예제 #4
0
        // Add a symmetric edge between two vertices if there's nothing blocking the way.
        // Returns whether the connection exists after the raycast.
        public static bool ConnectIfVisible(MyWayPoint v1, MyWayPoint v2)
        {
            if (v1 == v2)
            {
                return(true);
            }
            if (v1.Neighbors.Contains(v2))
            {
                return(true);
            }
            if (v1.Position == v2.Position)
            {
                Connect(v1, v2);
                return(true);
            }
            var line = new MyLine(v1.Position, v2.Position, true);

            if (MyEntities.GetAnyIntersectionWithLine(ref line, null, null, true, true, true, false) == null)
            {
                Connect(v1, v2);
                return(true);
            }
            return(false);
        }
예제 #5
0
        public override void UpdateBeforeSimulation()
        {
            if (MyGuiScreenGamePlay.Static.IsEditorActive() && !MyGuiScreenGamePlay.Static.IsIngameEditorActive())
            {
                base.UpdateBeforeSimulation();
                return;
            }

            if (!IsDummy)
            {
                // normal spawn or if we can spawn whole group
                bool spawnAllowed = m_spawnActivated;

                // Spawn in groups
                if (SpawnInGroups && spawnAllowed)
                {
                    foreach (Bot bot in m_botShips)
                    {
                        if ((bot.Ship != null && !bot.DoSpawn) || MyMinerGame.TotalGamePlayTimeInMilliseconds - bot.SpawnTime <= GetRespawnTime(bot))
                        {
                            spawnAllowed = false;
                            break;
                        }
                    }

                    if (spawnAllowed)
                    {
                        foreach (Bot bots in m_botShips)
                        {
                            bots.DoSpawn = true;
                        }
                    }
                    else
                    {
                        foreach (Bot bots in m_botShips)
                        {
                            if (bots.DoSpawn)
                            {
                                spawnAllowed = true;
                                break;
                            }
                        }
                    }
                }

                // Check if spawnpoint is visible
                if (MyFakes.ENABLE_VISIBLE_SPAWNPOINT_DEACTIVATION &&
                    spawnAllowed && LeftToSpawn != 0)
                {
                    MyLine line = new MyLine(MySession.PlayerShip.GetPosition(), GetPosition());
                    if (line.Length < 1000)
                    {
                        BoundingSphere boundingSphere = WorldVolume;
                        if (MyCamera.IsInFrustum(ref boundingSphere))
                        {
                            var intersection = MyEntities.GetAnyIntersectionWithLine(ref line, MySession.PlayerShip, null, true, true, false, true);

                            spawnAllowed = intersection.HasValue;
                        }
                    }
                }

                // Apply limiters
                foreach (var limiter in m_limiters)
                {
                    if (limiter.CurrentBotCount >= limiter.MaxBotCount)
                    {
                        spawnAllowed = false;
                    }
                }

                //Limit max count of spawned ships to 5
                for (int c = 0; c < Math.Min(m_botShips.Count, MAX_SPAWN_COUNT); c++)
                {
                    Bot bot = m_botShips[c];
                    // Only spawn when ships can be spawned
                    spawnAllowed &= LeftToSpawn != 0;

                    if (spawnAllowed)
                    {
                        //check if we can respawn ship
                        if (m_botShips[c].Ship == null &&
                            MyMinerGame.TotalGamePlayTimeInMilliseconds - bot.SpawnTime > GetRespawnTime(bot) &&
                            MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastSpawnTime > MIN_TIME_BETWEEN_BOT_SPAWN)
                        {
                            SpawnShip(c);

                            //Reset also when no bot was created, to avoid creation in each frame again and again..
                            if (m_botShips[c].Ship == null)
                            {
                                bot.SpawnTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; // reset timer
                            }
                        }
                    }
                }
            }

            for (int c = 0; c < m_botShips.Count; c++)
            {
                Bot bot = m_botShips[c];

                //reset spawning time
                if (bot.Ship != null)
                {
                    bot.SpawnTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; // reset timer
                }

                //dereference dead ship
                if (bot.Ship != null && bot.Ship.IsDead())
                {
                    bot.Ship      = null;
                    bot.SpawnTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;
                }
            }
            FirstSpawnDone = true;


            if (!m_allKilledEventRaised && LeftToSpawn == 0)
            {
                bool allKilled = true;
                foreach (var bot in m_botShips)
                {
                    if (bot.Ship != null && !bot.Ship.IsDead())
                    {
                        allKilled = false;
                    }
                }
                if (allKilled)
                {
                    MyScriptWrapper.OnSpawnpointBotsKilled(this);
                    m_allKilledEventRaised = true;
                }
            }

            base.UpdateBeforeSimulation();
        }
예제 #6
0
        public override bool DebugDraw()
        {            /*
                      * int i = MyWayPointGraph.GetConnectedComponentId(this);
                      * var vertexColor = HsvToRgb((0.36f + i * 0.618034f) % 1.0f, 0.8f, 0.75f);
                      *
                      * DrawWaypointVertex(WorldMatrix.Translation, vertexColor);  // draw only edges for generated waypoints
                      *
                      *
                      * // draw edges
                      * foreach (var neighbor in Neighbors)
                      * {
                      * //DrawWaypointEdge(wp.WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Red, Color.Green);  // selected path: red-green edges
                      *
                      * if (neighbor.WorldMatrix.Translation != WorldMatrix.Translation)
                      * {
                      * Vector3 direction = neighbor.WorldMatrix.Translation - WorldMatrix.Translation;
                      * float lineLength = direction.Length();
                      * direction.Normalize();
                      * MyTransparentGeometry.AddLineBillboard(MyTransparentMaterialEnum.ProjectileTrailLine, Color.Yellow.ToVector4(), WorldMatrix.Translation, direction, lineLength, 0.25f);
                      * }
                      *
                      * }
                      */
            if (((MyHud.ShowDebugWaypoints) || (MyGuiScreenGamePlay.Static.IsEditorActive() && !MyGuiScreenGamePlay.Static.IsIngameEditorActive())) && (MyFakes.ENABLE_GENERATED_WAYPOINTS_IN_EDITOR || MyHud.ShowDebugGeneratedWaypoints || Save))
            {
                // color by connected components
                int i           = MyWayPointGraph.GetConnectedComponentId(this);
                var vertexColor = HsvToRgb((0.36f + i * 0.618034f) % 1.0f, 0.8f, 0.75f);

                if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.WayPoints.Contains(this))
                {
                    vertexColor = Color.Orange.ToVector3();  // selected path: orange vertices
                }

                if (IsSecret)
                {
                    vertexColor *= 0.25f;
                }

                // draw vertices
                if (MyEditorGizmo.SelectedEntities.Contains(this))
                {
                    DrawWaypointVertex(WorldMatrix.Translation, vertexColor + (IsSecret ? 1 : 3) * GetHighlightColor());
                    var name = new StringBuilder();
                    if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.WayPoints.Contains(this))
                    {
                        name.Append(MyWayPointGraph.SelectedPath.Name).Append(": ").Append(MyWayPointGraph.SelectedPath.WayPoints.IndexOf(this) + 1);
                    }
                    else
                    {
                        name.Append(MyWayPoint.FilterWayPoints(MyEditorGizmo.SelectedEntities).IndexOf(this) + 1);
                    }
                    MyDebugDraw.DrawText(WorldMatrix.Translation, name, Color.White, 1);
                }
                else
                {
                    if (Save)
                    {
                        DrawWaypointVertex(WorldMatrix.Translation, vertexColor);  // for generated waypoints, draw only edges
                    }
                }

                // draw edges
                if (Save || MyHud.ShowDebugGeneratedWaypoints)
                {
                    using (MyWayPoint.NeighborsLock.AcquireSharedUsing())
                    {
                        foreach (var neighbor in Neighbors)
                        {
                            if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.ContainsEdge(this, neighbor))
                            {
                                DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Yellow, Color.White);  // on selected path: yellow-white
                                continue;
                            }

                            if (neighbor.Save || MyHud.ShowDebugGeneratedWaypoints)
                            {
                                using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                                {
                                    // blocked for player (by a locked indestructible door: white-gray)
                                    if (BlockedEdgesForPlayer.Contains(Tuple.Create(this, neighbor)) || BlockedEdgesForPlayer.Contains(Tuple.Create(neighbor, this)))
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.White, Color.Gray);
                                        continue;
                                    }

                                    // blocked for bots by a locked door: black-gray
                                    if (BlockedEdgesForBots.Contains(Tuple.Create(this, neighbor)) || BlockedEdgesForBots.Contains(Tuple.Create(neighbor, this)))
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Black, Color.Gray);
                                        continue;
                                    }
                                }

                                // obstructed: violet-white
                                if (MyHud.ShowDebugWaypointsCollisions && Position != neighbor.Position)
                                {
                                    var line = new MyLine(Position, neighbor.Position, true);
                                    if (MyEntities.GetAnyIntersectionWithLine(ref line, null, null, true, true, true, false) != null)
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Violet, Color.White);
                                        continue;
                                    }
                                }

                                // normal-normal: red-green
                                // generated-normal: orange-green (normally invisible)
                                // generated-generated: yellow-green (normally invisible)
                                bool generated      = !(Save && neighbor.Save);
                                bool fullyGenerated = !Save && !neighbor.Save;
                                DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, generated ? fullyGenerated ? Color.Yellow : Color.Orange : Color.Red, Color.Green);
                                continue;
                            }
                        }
                    }
                }
            }
            return(base.DebugDraw());
        }
예제 #7
0
        public void DoWork()
        {
            try
            {
                MyEntities.EntityCloseLock.AcquireShared();

                if (m_goalEntity == null)
                {
                    return;
                }
                // try the direct path
                {
                    var directLine = new MyLine(m_startPos, m_goalPos, true);
                    if (MyEntities.GetAnyIntersectionWithLine(ref directLine, m_goalEntity, null, true, true, true, false) == null)
                    {
                        Path.Add(m_startPos);
                        Path.Add(m_goalPos);
                        Message = new StringBuilder().AppendFormat(MyTextsWrapper.Get(MyTextsWrapperEnum.GPSDistance).ToString(), Vector3.Distance(m_startPos, m_goalPos));
                        return;
                    }
                }

                // get the closest waypoint to the goal (ignore visibility)
                MyWayPoint goal = MyWayPointGraph.GetClosestNonGeneratedWaypoint(m_goalPos);
                if (goal == null)
                {
                    return;
                }

                // remember which waypoints were visible/invisible from startPos
                // remember blocked/unblocked edges
                var visibleFromStartPosCache = new Dictionary <MyWayPoint, bool>();
                //var blockedEdges = new HashSet<Tuple<MyWayPoint, MyWayPoint>>();
                HashSet <Tuple <MyWayPoint, MyWayPoint> > blockedEdges = null;

                using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                {
                    blockedEdges = new HashSet <Tuple <MyWayPoint, MyWayPoint> >(MyWayPoint.BlockedEdgesForPlayer);
                }

                var unblockedEdges = new HashSet <Tuple <MyWayPoint, MyWayPoint> >();

                // get 7 closest visible waypoints to startPos and compute shortest paths from them

                // first try 7 closest
                var closestVisibleWaypoints = MyWayPointGraph.GetClosestVisibleWaypoints(m_startPos, m_goalEntity, 7, 7, visibleFromStartPosCache);

                if (closestVisibleWaypoints.Count == 0 || !FindPathBetweenWaypoints(closestVisibleWaypoints, goal, visibleFromStartPosCache, blockedEdges, unblockedEdges))
                {
                    // failure: try 50 closest
                    closestVisibleWaypoints = MyWayPointGraph.GetClosestVisibleWaypoints(m_startPos, m_goalEntity, 12, 50, visibleFromStartPosCache);

                    if (closestVisibleWaypoints.Count == 0 || !FindPathBetweenWaypoints(closestVisibleWaypoints, goal, visibleFromStartPosCache, blockedEdges, unblockedEdges))
                    {
                        return;  // no use
                    }
                }
            }
            finally
            {
                if (m_goalEntity != null)
                {
                    m_goalEntity.OnClose -= goalEntity_OnClose;
                }

                MyEntities.EntityCloseLock.ReleaseShared();
            }
        }