public void UpdateBeforeSimulation100() { m_soundEmitters[(int)MySoundEmitterEnum.PrimaryState].Update(); if (windSystem) { float oxygen = MyOxygenProviderSystem.GetOxygenInPoint(m_character.PositionComp.GetPosition()); if (oxygen > 0f) { inAtmosphere = true;//in pressurized environment } else { Vector3 gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(m_character.PositionComp.GetPosition()); if (gravity.LengthSquared() > 0f) { MyPlanet planet = MyGravityProviderSystem.GetNearestPlanet(m_character.PositionComp.GetPosition()); if (planet != null && planet.AtmosphereSettings.FogIntensity > 0f) { inAtmosphere = true;//in atmosphere without oxygen } else { inAtmosphere = false; } } else { inAtmosphere = false; } } windEmitter.Update(); } }
public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); m_waitForUpdate--; if (m_waitForUpdate > 0) { return; } m_waitForUpdate = UPDATE_DELAY; Vector3D position = MySector.MainCamera.Position; MyPlanet planet = MyGravityProviderSystem.GetNearestPlanet(position); if (planet != null) { var distanceFromPlanet = Vector3D.Distance(planet.PositionComp.GetPosition(), position); if (distanceFromPlanet > planet.MaximumRadius + Math.Max(100, planet.MaximumRadius)) { ; } planet = null; //too far planet } if (m_closestPlanet != planet) { m_closestPlanet = planet; if (m_closestPlanet != null) { MyStringId category = MyStringId.GetOrCompute(m_closestPlanet.Generator.Id.SubtypeId.ToString()); MyStringId transition = MyStringId.GetOrCompute(m_closestPlanet.Generator.Id.SubtypeId.ToString()); if (!MyAudio.Static.IsValidTransitionCategory(transition, category)) { category = MyStringId.GetOrCompute("OtherPlanet"); transition = MyStringId.GetOrCompute("OtherPlanet"); } MyMusicTrack mt = new MyMusicTrack() { MusicCategory = category, TransitionCategory = transition }; MyAudio.Static.PlayMusic(mt); } else { //random MyMusicTrack mt = new MyMusicTrack() { }; MyAudio.Static.PlayMusic(mt, 1); } } }
public void UpdateAtmosphereStatus() { if (m_character != null && (m_localPlayer == false || (MySession.Static != null && m_character == MySession.Static.LocalCharacter))) { AtmosphereStatus original = m_atmosphereStatus; Vector3D pos = m_character.PositionComp.GetPosition(); Vector3 gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(pos); if (gravity.LengthSquared() > 0f) { MyPlanet planet = MyGravityProviderSystem.GetNearestPlanet(pos); if (planet != null && planet.HasAtmosphere && planet.GetAirDensity(pos) > 0.5f) { m_atmosphereStatus = AtmosphereStatus.Atmosphere;//in atmosphere } else { m_atmosphereStatus = AtmosphereStatus.Space; } } else { m_atmosphereStatus = AtmosphereStatus.Space; } if (m_atmosphereStatus == AtmosphereStatus.Space) { float oxygen = 0f; if (m_character.OxygenComponent != null) { if (m_localPlayer) { if (MySession.Static.ControlledEntity is MyCharacter) { //in suit oxygen = m_character.OxygenComponent.EnvironmentOxygenLevel; } else { //in cockpit oxygen = m_character.OxygenComponent.OxygenLevelAtCharacterLocation; } } else { oxygen = m_character.OxygenComponent.EnvironmentOxygenLevel; } } if (oxygen > 0.1f) { m_atmosphereStatus = AtmosphereStatus.ShipOrStation;//in pressurized environment } } if (MyFakes.ENABLE_REALISTIC_LIMITER && MyFakes.ENABLE_NEW_SOUNDS && original != m_atmosphereStatus && MySession.Static != null && MySession.Static.Settings.RealisticSound) { MyAudio.Static.EnableMasterLimiter(!(InAtmosphere || InShipOrStation)); } } }
public SpawnInfo(MyObjectBuilder_SpaceFaunaComponent.SpawnInfo info, int currentTime) { SpawnTime = currentTime + info.SpawnTime; AbandonTime = currentTime + info.SpawnTime; Position = new Vector3D(info.X, info.Y, info.Z); Planet = MyGravityProviderSystem.GetNearestPlanet(Position); SpawnDone = false; }
private static MyPlanet FindNearestPlanet(Vector3D worldPosition) { MyPlanet foundPlanet = MyGravityProviderSystem.GetNearestPlanet(worldPosition); if (foundPlanet != null && !((IMyGravityProvider)foundPlanet).IsPositionInRange(worldPosition)) { foundPlanet = null; } return(foundPlanet); }
public void UpdateAtmosphereStatus() { if (m_character != null && (m_localPlayer == false || (MySession.Static != null && m_character == MySession.Static.LocalCharacter))) { Vector3D pos = m_character.PositionComp.GetPosition(); Vector3 gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(pos); if (gravity.LengthSquared() > 0f) { MyPlanet planet = MyGravityProviderSystem.GetNearestPlanet(pos); float d = (float)Vector3D.DistanceSquared(planet.PositionComp.GetPosition(), pos); if (planet != null && planet.HasAtmosphere && Vector3D.DistanceSquared(planet.PositionComp.GetPosition(), pos) < planet.AtmosphereRadius * planet.AtmosphereRadius) { m_atmosphereStatus = AtmosphereStatus.Atmosphere;//in atmosphere } else { m_atmosphereStatus = AtmosphereStatus.Space; } } else { m_atmosphereStatus = AtmosphereStatus.Space; } if (m_atmosphereStatus == AtmosphereStatus.Space) { float oxygen = 0f; if (m_character.OxygenComponent != null) { if (m_localPlayer) { if (MySession.Static.ControlledEntity is MyCharacter) { //in suit oxygen = m_character.OxygenComponent.EnvironmentOxygenLevel; } else { //in cockpit oxygen = m_character.OxygenComponent.OxygenLevelAtCharacterLocation; } } else { oxygen = m_character.OxygenComponent.EnvironmentOxygenLevel; } } if (oxygen > 0.1f) { m_atmosphereStatus = AtmosphereStatus.ShipOrStation;//in pressurized environment } } } }
public SpawnTimeoutInfo(MyObjectBuilder_SpaceFaunaComponent.TimeoutInfo info, int currentTime) { TimeoutTime = currentTime + info.Timeout; Position = new Vector3D(info.X, info.Y, info.Z); var planet = MyGravityProviderSystem.GetNearestPlanet(Position); AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position); if (AnimalSpawnInfo == null) { TimeoutTime = currentTime; } }
public SpawnTimeoutInfo(Vector3D position, int currentTime) { TimeoutTime = currentTime; Position = position; var planet = MyGravityProviderSystem.GetNearestPlanet(Position); Debug.Assert(planet != null); AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position); if (AnimalSpawnInfo == null) { TimeoutTime = currentTime; } }
protected MyBehaviorTreeState Teleport() { if (Bot.Player.Character.HasAnimation("Deburrow")) { Bot.Player.Character.PlayCharacterAnimation("Deburrow", MyBlendOption.Immediate, MyFrameOption.JustFirstFrame, 0.0f, 1, sync: true); Bot.AgentEntity.DisableAnimationCommands(); } MatrixD teleportPos; bool success = MySpaceBotFactory.GetSpiderSpawnPosition(out teleportPos, Bot.Player.GetPosition()); if (!success) { return(MyBehaviorTreeState.FAILURE); } Vector3D pos = teleportPos.Translation; float radius = (float)Bot.AgentEntity.PositionComp.WorldVolume.Radius; var planet = MyGravityProviderSystem.GetNearestPlanet(pos); if (planet != null) { planet.CorrectSpawnLocation(ref pos, radius); teleportPos.Translation = pos; } else { Vector3D?freePlace = MyEntities.FindFreePlace(teleportPos.Translation, radius, stepSize: 0.2f); if (freePlace.HasValue) { teleportPos.Translation = freePlace.Value; } } Bot.AgentEntity.SetPhysicsEnabled(false); Bot.AgentEntity.WorldMatrix = teleportPos; Bot.AgentEntity.Physics.CharacterProxy.Up = teleportPos.Up; Bot.AgentEntity.Physics.CharacterProxy.Forward = teleportPos.Forward; Bot.AgentEntity.SetPhysicsEnabled(true); return(MyBehaviorTreeState.SUCCESS); }
protected MyBehaviorTreeState GetTargetWithPriority([BTParam] float radius, [BTInOut] ref MyBBMemoryTarget outTarget, [BTInOut] ref MyBBMemoryInt priority) { if (CyberhoundLogic.SelfDestructionActivated) // self destruction activated, do not change target. { return(MyBehaviorTreeState.SUCCESS); } var myPosition = Bot.Navigation.PositionAndOrientation.Translation; BoundingSphereD bb = new BoundingSphereD(myPosition, radius); if (priority == null) { priority = new MyBBMemoryInt(); } int bestPriority = priority.IntValue; if (bestPriority <= 0 || Bot.Navigation.Stuck) { bestPriority = int.MaxValue; } MyBehaviorTreeState retval = IsTargetValid(ref outTarget); if (retval == MyBehaviorTreeState.FAILURE) { bestPriority = 7; MyBBMemoryTarget.UnsetTarget(ref outTarget); } Vector3D?targetPosition = CyberhoundTarget.GetMemoryTargetPosition(outTarget); if (!targetPosition.HasValue || Vector3D.DistanceSquared(targetPosition.Value, Bot.AgentEntity.PositionComp.GetPosition()) > 400.0f * 400.0f) { bestPriority = 7; MyBBMemoryTarget.UnsetTarget(ref outTarget); } if (targetPosition.HasValue) { Vector3D targetPositionValue = targetPosition.Value; var planet = MyGravityProviderSystem.GetNearestPlanet(targetPositionValue); if (planet != null) { Vector3D targetPositionProjected = planet.GetClosestSurfacePointGlobal(ref targetPositionValue); if (Vector3D.DistanceSquared(targetPositionProjected, targetPositionValue) > 1.5f * 1.5f && Vector3D.DistanceSquared(targetPositionProjected, Bot.AgentEntity.PositionComp.GetPosition()) < 5.0f * 5.0f) { bestPriority = 7; MyBBMemoryTarget.UnsetTarget(ref outTarget); } } } var myFaction = MySession.Static.Factions.GetPlayerFaction(Bot.AgentEntity.ControllerInfo.ControllingIdentityId); // Priorities are as follows: // 1st characters, 3rd turrets, 4th weapons, 5th non-armor blocks, 6th armor blocks var entityList = MyEntities.GetTopMostEntitiesInSphere(ref bb); entityList.ShuffleList(); // Prevent all Cyberhounds going for the same player foreach (var entity in entityList) { if (entity == Bot.AgentEntity || entity is MyVoxelBase || !CyberhoundTarget.IsEntityReachable(entity)) { continue; } // exclude entities above ground Vector3D entityPos = entity.PositionComp.GetPosition(); var planet = MyGravityProviderSystem.GetNearestPlanet(entityPos); if (planet != null) { Vector3D entityPosProjected = planet.GetClosestSurfacePointGlobal(ref entityPos); if (Vector3D.DistanceSquared(entityPosProjected, entityPos) > 1.0f) { continue; } } int entityPriority = 6; var character = entity as MyCharacter; var grid = entity as MyCubeGrid; if (character != null) { var faction = MySession.Static.Factions.GetPlayerFaction(character.ControllerInfo.ControllingIdentityId); if (myFaction != null && faction == myFaction) { continue; } if (character.IsDead) { continue; } entityPriority = 1; if (entityPriority < bestPriority) { retval = MyBehaviorTreeState.SUCCESS; bestPriority = entityPriority; MyBBMemoryTarget.SetTargetEntity(ref outTarget, MyAiTargetEnum.CHARACTER, character.EntityId); lastTargetedEntityPosition = character.PositionComp.GetPosition(); continue; } } else if (grid != null && bestPriority > 3) { Vector3D CyberhoundPosInGrid = grid.WorldToGridScaledLocal(myPosition); double closestDist = double.MaxValue; MySlimBlock closestBlock = null; foreach (var block in grid.CubeBlocks) { Vector3D blockLocalPos = new Vector3D(block.Min + block.Max); blockLocalPos = blockLocalPos * 0.5; double dist = Vector3D.RectangularDistance(ref blockLocalPos, ref CyberhoundPosInGrid); if (dist < closestDist) { closestBlock = block; closestDist = dist; } } if (closestBlock != null) { retval = MyBehaviorTreeState.SUCCESS; bestPriority = 3; MyBBMemoryTarget.SetTargetCube(ref outTarget, (closestBlock.Min + closestBlock.Max) / 2, grid.EntityId); BoundingBoxD bbBlock; closestBlock.GetWorldBoundingBox(out bbBlock); lastTargetedEntityPosition = bbBlock.Center; } } } entityList.Clear(); priority.IntValue = bestPriority; // CH: TODO: This is temporary. Remove it! if (outTarget.TargetType == MyAiTargetEnum.CUBE) { MyEntity outGrid; MyEntities.TryGetEntityById(outTarget.EntityId.Value, out outGrid); Debug.Assert(outGrid != null); var grid = outGrid as MyCubeGrid; MySlimBlock block = grid.GetCubeBlock(outTarget.BlockPosition); Debug.Assert(block != null); //MyTrace.Send(TraceWindow.Ai, "TARGETTING CUBE: " + grid.ToString() + " " + block.ToString()); } if (outTarget.TargetType == MyAiTargetEnum.NO_TARGET) { retval = MyBehaviorTreeState.FAILURE; } return(retval); }
protected MyBehaviorTreeState RunAway([BTParam] float distance) { if (!runAwayPos.HasValue) { Vector3D currentPosition = Bot.Player.Character.PositionComp.GetPosition(); Vector3D planetGravityVec = MyGravityProviderSystem.CalculateNaturalGravityInPoint(currentPosition); var planet = MyGravityProviderSystem.GetNearestPlanet(currentPosition); if (planet == null) { return(MyBehaviorTreeState.FAILURE); } if (lastTargetedEntityPosition.HasValue) { Vector3D lastTargetedEntityPositionProjected = lastTargetedEntityPosition.Value; lastTargetedEntityPositionProjected = planet.GetClosestSurfacePointGlobal(ref lastTargetedEntityPositionProjected); Vector3D direction = currentPosition - lastTargetedEntityPositionProjected; Vector3D runAwayPosCandidate = currentPosition + Vector3D.Normalize(direction) * distance; runAwayPos = planet.GetClosestSurfacePointGlobal(ref runAwayPosCandidate); } else { planetGravityVec.Normalize(); Vector3D planetTangent = Vector3D.CalculatePerpendicularVector(planetGravityVec); Vector3D planetBitangent = Vector3D.Cross(planetGravityVec, planetTangent); planetTangent.Normalize(); planetBitangent.Normalize(); Vector3D runAwayPosCandidate = MyUtils.GetRandomDiscPosition(ref currentPosition, distance, distance, ref planetTangent, ref planetBitangent); if (planet != null) { runAwayPos = planet.GetClosestSurfacePointGlobal(ref runAwayPosCandidate); } else { runAwayPos = runAwayPosCandidate; } } AiTargetBase.SetTargetPosition(runAwayPos.Value); AimWithMovement(); } else { if (Bot.Navigation.Stuck) { return(MyBehaviorTreeState.FAILURE); } } AiTargetBase.GotoTargetNoPath(1.0f, false); if (Vector3D.DistanceSquared(runAwayPos.Value, Bot.Player.Character.PositionComp.GetPosition()) < 10.0f * 10.0f) { CyberhoundLogic.Remove(); return(MyBehaviorTreeState.SUCCESS); } else { return(MyBehaviorTreeState.RUNNING); } }
private void CalculateNextCue() { if (MySession.Static == null || MySession.Static.LocalCharacter == null) { return; } m_noMusicTimer = m_random.Next(DEFAULT_NO_MUSIC_TIME_MIN, DEFAULT_NO_MUSIC_TIME_MAX); //planet or space Vector3D pos = MySession.Static.LocalCharacter.PositionComp.GetPosition(); MyPlanet planet = MyGravityProviderSystem.GetNearestPlanet(pos); if (planet != null && Vector3D.Distance(pos, planet.PositionComp.GetPosition()) <= planet.GravityLimit * 0.65f) { if (planet != m_lastVisitedPlanet) { m_lastVisitedPlanet = planet; if (planet.Generator.MusicCategories != null && planet.Generator.MusicCategories.Count > 0) { m_actualMusicOptions.Clear(); foreach (var option in planet.Generator.MusicCategories) { m_actualMusicOptions.Add(new MusicOption(option.Category, option.Frequency)); } } else { m_actualMusicOptions = m_defaultPlanetCategory; } } } else { m_lastVisitedPlanet = null; m_actualMusicOptions = m_defaultSpaceCategories; } //choose category based on frequency float sum = 0f; foreach (var option in m_actualMusicOptions) { sum += Math.Max(option.Frequency, 0f); } float r = (float)m_random.NextDouble() * sum; MyStringId selected = m_actualMusicOptions[0].Category; for (int i = 0; i < m_actualMusicOptions.Count; i++) { if (r <= m_actualMusicOptions[i].Frequency) { selected = m_actualMusicOptions[i].Category; break; } else { r -= m_actualMusicOptions[i].Frequency; } } //pick from cue list and play CueIdPlaying = SelectCueFromCategory(selected); CategoryPlaying = selected; if (CueIdPlaying == m_cueEmpty) { return; } PlayMusic(CueIdPlaying, MyStringHash.NullOrEmpty); m_currentMusicCategory = MusicCategory.location; }
public override void UpdateBeforeSimulation() { return; base.UpdateBeforeSimulation(); if (m_particleSpawnCounter-- > 0) { return; } var entity = MySession.Static.ControlledEntity as MyEntity; if (entity == null) { return; } var controlledEntity = entity.GetTopMostParent(); if (controlledEntity == null) { return; } try { ProfilerShort.Begin("Grassland.UpdateBeforeSimulation"); m_particleSpawnCounter = (int)Math.Round(m_particleSpawnCounter + m_particleSpawnCounter * m_particleSpawnIntervalRandomness * (MyRandom.Instance.NextFloat() * 2.0f - 1.0f)); if (MyRandom.Instance.FloatNormal() <= m_particleDensity) { return; } var cameraPosition = MySector.MainCamera.Position; MyPlanet nearestPlanet = MyGravityProviderSystem.GetNearestPlanet(cameraPosition); Vector3D naturalGravity = nearestPlanet.GetWorldGravityGrid(MySector.MainCamera.Position); if (naturalGravity.Dot(MySector.DirectionToSunNormalized) > 0) // Only spawn during the day { return; } var velocity = (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator ? Vector3.Zero : controlledEntity.Physics.LinearVelocity); var speed = velocity.Length(); var cameraPositionLocal = Vector3D.Transform(cameraPosition, MatrixD.Invert(nearestPlanet.WorldMatrix)); //Vector3D nearestSurfacePointLocal = nearestPlanet.GetClosestSurfacePointLocal(cameraPosition); // Vector3D nearestSurfacePointWorld = Vector3D.Transform(nearestSurfacePointLocal, nearestPlanet.WorldMatrix); // bool test = nearestPlanet.IsFloraAtPosition(nearestSurfacePointLocal); var currentCharacter = controlledEntity as MyCharacter; float characterFlyingMaxSpeed = (currentCharacter != null) ? currentCharacter.Physics.CharacterProxy.CharacterFlyingMaxLinearVelocity() : MyGridPhysics.ShipMaxLinearVelocity(); Vector3 halfExtents = Vector3.One * m_particleSpawnDistance; if (speed / characterFlyingMaxSpeed > 1.0f) { halfExtents += 10.0f * velocity / characterFlyingMaxSpeed; } var entityTranslation = cameraPosition; var searchPosition = entityTranslation + velocity; MyPhysics.GetPenetrationsBox(ref halfExtents, ref searchPosition, ref Quaternion.Identity, m_bodyCollisions, MyPhysics.CollisionLayers.NotCollideWithStaticLayer); var spawnPosition = default(Vector3D); bool spawnPositionFound = false; foreach (var foundEntity in m_bodyCollisions) { var environmentItems = foundEntity.Body.GetEntity(foundEntity.ShapeKey) as MyEnvironmentItems; if (environmentItems != null) { environmentItems.GetAllItemsInRadius(searchPosition, m_particleSpawnDistance, m_tmpItemInfos); } } if (m_tmpItemInfos.Count != 0) { int selectedTreeIndex = MyRandom.Instance.Next(0, m_tmpItemInfos.Count - 1); spawnPosition = m_tmpItemInfos[selectedTreeIndex].Transform.Position; spawnPositionFound = true; } if (!spawnPositionFound) { return; } var spawnedParticle = Spawn(spawnPosition); if (spawnedParticle == null) { return; } InitializePath(spawnedParticle); } finally { m_bodyCollisions.Clear(); ProfilerShort.End(); } }
public static bool GetSpiderSpawnPosition(out MatrixD spawnPosition, Vector3D?oldPosition) { spawnPosition = MatrixD.Identity; Vector3D?position = null; MyPlanet planet = null; foreach (var player in Sync.Players.GetOnlinePlayers()) { if (player.Id.SerialId != 0) { continue; } if (player.Character == null) { continue; } position = player.GetPosition(); planet = MyGravityProviderSystem.GetNearestPlanet(position.Value); var animalSpawnInfo = GetDayOrNightAnimalSpawnInfo(planet, position.Value); if (animalSpawnInfo == null || animalSpawnInfo.Animals == null || !animalSpawnInfo.Animals.Any(x => x.AnimalType.Contains("Spider"))) { position = null; planet = null; continue; } if (oldPosition != null) // prevent teleporting from planet to planet { var planetOld = MyGravityProviderSystem.GetNearestPlanet(oldPosition.Value); if (planet != planetOld) { position = null; planet = null; continue; } } break; } if (!position.HasValue || planet == null) { return(false); } Vector3D gravity = planet.GetWorldGravity(position.Value); if (Vector3D.IsZero(gravity)) { gravity = Vector3D.Down; } else { gravity.Normalize(); } Vector3D tangent, bitangent; gravity.CalculatePerpendicularVector(out tangent); bitangent = Vector3D.Cross(gravity, tangent); Vector3D start = position.Value; start = MyUtils.GetRandomDiscPosition(ref start, 20.0f, ref tangent, ref bitangent); start -= gravity * 500; Vector3D translation = planet.GetClosestSurfacePointGlobal(ref start); Vector3D dirToPlayer = position.Value - translation; if (!Vector3D.IsZero(dirToPlayer)) { dirToPlayer.Normalize(); } else { dirToPlayer = Vector3D.CalculatePerpendicularVector(gravity); } spawnPosition = MatrixD.CreateWorld(translation, dirToPlayer, -gravity); return(true); }
public override void UpdateAfterSimulation() { base.UpdateAfterSimulation(); if (!Sync.IsServer) { return; } if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_FAUNA_COMPONENT) { DebugDraw(); } ProfilerShort.Begin("MySpaceFaunaComponent.UpdateAfter"); m_waitForUpdate--; if (m_waitForUpdate > 0) { return; } m_waitForUpdate = UPDATE_DELAY; var players = Sync.Players.GetOnlinePlayers(); m_tmpPlayerPositions.Capacity = Math.Max(m_tmpPlayerPositions.Capacity, players.Count); m_tmpPlayerPositions.Clear(); // Reset bot numbers foreach (var planet in m_planets) { planet.Value.BotNumber = 0; } // Update bot numbers and save player positions foreach (var player in players) { // Human player if (player.Id.SerialId == 0) { if (player.Controller.ControlledEntity == null) { continue; } var pos = player.GetPosition(); m_tmpPlayerPositions.Add(pos); } // Bot else { if (player.Controller.ControlledEntity == null) { continue; } var pos = player.GetPosition(); var planet = MyGravityProviderSystem.GetNearestPlanet(pos); if (planet != null && planet.IsPositionInGravityWell(pos)) { PlanetAIInfo planetInfo; if (m_planets.TryGetValue(planet.EntityId, out planetInfo)) { planetInfo.BotNumber++; } } } } int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; // Spawn bots near players on planets, only if in survival/myfakes macro set if (MyFakes.SPAWN_SPACE_FAUNA_IN_CREATIVE) { foreach (var player in players) { if (player.Controller.ControlledEntity == null) { continue; } var pos = player.GetPosition(); var planet = MyGravityProviderSystem.GetNearestPlanet(pos); if (planet == null || !planet.IsPositionInGravityWell(pos) || !PlanetHasFauna(planet)) { continue; } PlanetAIInfo planetInfo = null; if (!m_planets.TryGetValue(planet.EntityId, out planetInfo)) { continue; } // Human player - spawn spiders if (player.Id.SerialId == 0) { // Distance to surface check Vector3D toSurface = planet.GetClosestSurfacePointGlobal(ref pos) - pos; if (toSurface.LengthSquared() >= PROXIMITY_DIST * PROXIMITY_DIST && planetInfo.BotNumber >= MAX_BOTS_PER_PLANET) { continue; } int spawnPointCount = 0; var pointEnum = m_spawnInfoGrid.GetPointsCloserThan(ref pos, SPHERE_SPAWN_DIST); while (pointEnum.MoveNext()) { var spawnPoint = pointEnum.Current; spawnPointCount++; if (spawnPoint.SpawnDone) { continue; // Don't take not-yet cleaned spawn info into consideration } if (spawnPoint.ShouldSpawn(currentTime)) { spawnPoint.SpawnDone = true; var timeouts = m_timeoutInfoGrid.GetPointsCloserThan(ref pos, TIMEOUT_DIST); bool timeoutPresent = false; while (timeouts.MoveNext()) { if (timeouts.Current.IsTimedOut(currentTime)) { continue; } timeoutPresent = true; break; } if (timeoutPresent) { continue; } var animalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, spawnPoint.Position); if (animalSpawnInfo == null) { continue; } int numBots = MyUtils.GetRandomInt(animalSpawnInfo.WaveCountMin, animalSpawnInfo.WaveCountMax); for (int i = 0; i < numBots; ++i) { SpawnBot(spawnPoint, planet, animalSpawnInfo); } } else { spawnPoint.UpdateAbandoned(currentTime); } } if (spawnPointCount == 0) // we dont have any spawn points near human players position { var spawnInfo = new SpawnInfo(pos, currentTime, planet); m_spawnInfoGrid.AddPoint(ref pos, spawnInfo); m_allSpawnInfos.Add(spawnInfo); } } // Despawn bots that are too far from all players else //if (player.Id.SteamId == Sync.MyId) { double closestDistSq = double.MaxValue; foreach (Vector3D playerPosition in m_tmpPlayerPositions) { closestDistSq = Math.Min(Vector3D.DistanceSquared(pos, playerPosition), closestDistSq); } if (closestDistSq > DESPAWN_DIST * DESPAWN_DIST) { MyAIComponent.Static.RemoveBot(player.Id.SerialId, removeCharacter: true); } } } } m_tmpPlayerPositions.Clear(); m_waitForClean -= UPDATE_DELAY; if (m_waitForClean <= 0) { MyAIComponent.Static.CleanUnusedIdentities(); m_waitForClean = CLEAN_DELAY; for (int i = 0; i < m_allSpawnInfos.Count; ++i) { var spawnInfo = m_allSpawnInfos[i]; if (spawnInfo.IsAbandoned(currentTime) || spawnInfo.SpawnDone) { m_allSpawnInfos.RemoveAtFast(i); Vector3D point = spawnInfo.Position; m_spawnInfoGrid.RemovePoint(ref point); --i; } } for (int i = 0; i < m_allTimeoutInfos.Count; ++i) { var timeoutInfo = m_allTimeoutInfos[i]; if (timeoutInfo.IsTimedOut(currentTime)) { m_allTimeoutInfos.RemoveAtFast(i); Vector3D point = timeoutInfo.Position; m_timeoutInfoGrid.RemovePoint(ref point); --i; } } } ProfilerShort.End(); }