/// <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); }
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); }
// 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); }
// 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); }
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(); }
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()); }
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(); } }