private Vector3D?FindFreePlace(Vector3D start, float rad, float step) { var probe = _positionComponent.WorldMatrix.Up; var direction = Definition.SpawnOffset.Translation; var len = direction.Length(); if (len >= 1e-6f) { probe = Vector3D.TransformNormal(direction / len, _positionComponent.WorldMatrix); } for (var i = 0; i < 20; i++) { var test = start + i * step * probe; if (MyEntities.FindFreePlace(test, rad, -1, 1, 1f, true).HasValue) { // cast ray back inwards (because silly, silly phantoms) IHitInfo hit; if (!MyAPIGateway.Physics.CastRay(test, start, out hit, 9)) { return(start); } return(hit.Position + Vector3.Normalize(test - start) * rad); } } return(null); }
public override bool HandleInputAfterSimulation() { if (m_respawnsTable.SelectedRow != null && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity) { MyMedicalRoomInfo userData = m_respawnsTable.SelectedRow.UserData as MyMedicalRoomInfo; if (userData != null) { m_respawnButton.Enabled = false; MyMedicalRoom medicalRoom; if (MyEntities.TryGetEntityById <MyMedicalRoom>(userData.MedicalRoomId, out medicalRoom)) { m_respawnButton.Enabled = true; Vector3D medRoomPosition = (Vector3D)medicalRoom.PositionComp.GetPosition(); Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20; Vector3D?cameraPosition = MyEntities.FindFreePlace(preferredCameraPosition, 1); if (!cameraPosition.HasValue) { cameraPosition = preferredCameraPosition; } MySpectatorCameraController.Static.Position = cameraPosition.Value; MySpectatorCameraController.Static.SetTarget(medRoomPosition, medicalRoom.WorldMatrix.Up); } } } return(true); }
private void OnTableItemSelected(MyGuiControlTable sender, MyGuiControlTable.EventArgs eventArgs) { if (m_respawnsTable.SelectedRow != null) { m_respawnButton.Enabled = true; if (m_respawnsTable.SelectedRow.UserData == null || m_respawnsTable.SelectedRow.UserData as MyMedicalRoom == null) { MySession.SetCameraController(MyCameraControllerEnum.Spectator, null, new Vector3D(1000000)); //just somewhere out of the game area to see our beautiful skybox return; } MyMedicalRoom medicalRoom = (MyMedicalRoom)m_respawnsTable.SelectedRow.UserData; Vector3D medRoomPosition = (Vector3D)medicalRoom.PositionComp.GetPosition(); Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20; Vector3D? cameraPosition = MyEntities.FindFreePlace(preferredCameraPosition, 1); if (!cameraPosition.HasValue) { cameraPosition = preferredCameraPosition; } MySession.SetCameraController(MyCameraControllerEnum.Spectator, null, cameraPosition); MySpectatorCameraController.Static.Target = (Vector3D)medRoomPosition; } else { m_respawnButton.Enabled = false; } }
// /admin movefrom x y z x y z radius public override bool HandleCommand(ulong userId, string[] words) { if (words.Count() != 4 && words.Count() != 0) { return(false); } if (words.Count() != 4) { Communication.SendPrivateInformation(userId, GetHelp()); return(true); } // Test Input float test = 0; for (int r = 1; r < 4; r++) { if (!float.TryParse(words[r], out test)) { Communication.SendPrivateInformation(userId, string.Format("The value at position {0} - '{1}' is invalid. Please try the command again.", r + 1, words[r])); return(true); } } string userName = words[0]; Vector3D startPosition = new Vector3D(double.Parse(words[1]), double.Parse(words[2]), double.Parse(words[3])); List <IMyPlayer> players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, x => x.DisplayName.Contains(userName, StringComparison.CurrentCultureIgnoreCase)); if (players[0] == null) { Communication.SendPrivateInformation(userId, $"Couldn't find player with name {userName}."); return(true); } MyEntity controlledEntity = ((MyEntity)players[0].Controller.ControlledEntity).GetTopMostParent( ); float size = 2.5f; if (controlledEntity is MyCubeGrid) { size = (float)((MyCubeGrid)controlledEntity).PositionComp.WorldAABB.Extents.Max( ); } //make sure we aren't moving the player inside a planet or something Vector3D?testPos = null; Wrapper.GameAction(() => testPos = MyEntities.FindFreePlace(startPosition, size)); if (testPos == null) { Communication.SendPrivateInformation(userId, $"Could not move player: {userName}. Position is not empty, try another."); return(true); } //server controls movement now Wrapper.GameAction(() => controlledEntity.PositionComp.SetPosition(testPos.Value)); return(true); }
public static void GetSpawnPosition(float collisionRadius, out Vector3 direction, out Vector3 position) { float distance = 0; foreach (var entity in MyEntities.GetEntities()) { // Include only voxels if (entity is MyVoxelMap) { distance = (float)MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius); } } // 500 - 650m from last voxel distance += MyUtils.GetRandomFloat(500, 650); if (MyEntities.IsWorldLimited()) { distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent()); } else { distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds } direction = MyUtils.GetRandomVector3Normalized(); var searchPosition = MyEntities.FindFreePlace((Vector3D)(direction * distance), collisionRadius); if (!searchPosition.HasValue) { searchPosition = (Vector3D)(direction * distance); // Spawn in existing place (better than crash) } position = (Vector3)searchPosition.Value; }
private void SpawnBot(SpawnInfo spawnInfo, MyPlanet planet, MyPlanetAnimalSpawnInfo animalSpawnInfo) { PlanetAIInfo planetInfo = null; if (!m_planets.TryGetValue(planet.EntityId, out planetInfo)) { Debug.Assert(false, "Could not get planet info!"); return; } if (planetInfo.BotNumber >= MAX_BOTS_PER_PLANET) { return; } Debug.Assert(animalSpawnInfo != null); double spawnDistMin = animalSpawnInfo.SpawnDistMin; double spawnDistMax = animalSpawnInfo.SpawnDistMax; Vector3D center = spawnInfo.Position; Vector3D planetGravityVec = MyGravityProviderSystem.CalculateNaturalGravityInPoint(center); //GR: if gravity is zero provide a random Vector to normalize if (planetGravityVec == Vector3D.Zero) { planetGravityVec = Vector3D.Up; } planetGravityVec.Normalize(); Vector3D planetTangent = Vector3D.CalculatePerpendicularVector(planetGravityVec); Vector3D planetBitangent = Vector3D.Cross(planetGravityVec, planetTangent); planetTangent.Normalize(); planetBitangent.Normalize(); Vector3D spawnPos = MyUtils.GetRandomDiscPosition(ref center, spawnDistMin, spawnDistMax, ref planetTangent, ref planetBitangent); spawnPos = planet.GetClosestSurfacePointGlobal(ref spawnPos); Vector3D?spawnPosCorrected = MyEntities.FindFreePlace(spawnPos, 2.0f); if (spawnPosCorrected.HasValue) { spawnPos = spawnPosCorrected.Value; } planet.CorrectSpawnLocation(ref spawnPos, 2.0f); MyAgentDefinition botBehavior = GetAnimalDefinition(animalSpawnInfo) as MyAgentDefinition; if (botBehavior != null) { if (botBehavior.Id.SubtypeName == Wolf_SUBTYPE_ID && MySession.Static.EnableWolfs) { MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos); } else if (botBehavior.Id.SubtypeName != Wolf_SUBTYPE_ID && MySession.Static.EnableSpiders) { MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos); } } }
private Vector3D?FindPastePosition(MyObjectBuilder_CubeGrid[] grids, Vector3D playerPosition) { BoundingSphere sphere = FindBoundingSphere(grids); /* * Now we know the radius that can house all grids which will now be * used to determine the perfect place to paste the grids to. */ return(MyEntities.FindFreePlace(playerPosition, sphere.Radius)); }
/// <summary> /// Returns a position that should be safe to spawn at given the radius and position. /// </summary> /// <param name="collisionRadius">The radius of the object that is trying to spawn.</param> /// <param name="position">The position the object would like to spawn at.</param> /// <param name="forward">(Out) The forward vector the object should spawn with.</param> /// <param name="up">(Out) The up vector the object should spawn with.</param> /// <param name="planetSpawnHeightRatio">The ratio within the planet's max radius and atmosphere radius you are positioned in.</param> /// <param name="randomRangeMin">The minimum randomized distance that is added.</param> /// <param name="randomRangeMax">The minimum randomized distance that is added.</param> public static void GetSpawnPosition(float collisionRadius, ref Vector3D position, out Vector3D forward, out Vector3D up, float planetSpawnHeightRatio = 0.3f, float randomRangeMin = 500, float randomRangeMax = 650) { // Are we spawning near a planet? MyPlanet planet = MyGamePruningStructure.GetClosestPlanet(position); if (planet != null) { GetSpawnPositionNearPlanet(planet, collisionRadius, ref position, out forward, out up, planetSpawnHeightRatio, randomRangeMin, randomRangeMax); return; } // Old logic, testing for asteroids and other objects double distance = 0; foreach (var entity in MyEntities.GetEntities()) { MyVoxelMap voxelMap = entity as MyVoxelMap; // Only test against voxels if (entity == null) { continue; } distance = MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius); } // Random range from last voxel distance += MyUtils.GetRandomFloat(randomRangeMin, randomRangeMax); if (MyEntities.IsWorldLimited()) { distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent()); } else { distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds } // Compute random position forward = MyUtils.GetRandomVector3Normalized(); up = Vector3D.CalculatePerpendicularVector(forward); Vector3D randomizedPosition = position + (forward * distance); // Test if we can spawn here Vector3D?searchPosition = MyEntities.FindFreePlace(randomizedPosition, collisionRadius); if (searchPosition.HasValue) { randomizedPosition = searchPosition.Value; } position = randomizedPosition; }
public void SpawnAt(MatrixD worldMatrix, Vector3 velocity, MyEntity spawnedBy, MyBotDefinition botDefinition, bool findFreePlace = true) { Debug.Assert(Sync.IsServer, "Spawning can be called only on the server!"); Debug.Assert(Identity != null, "Spawning with empty identity!"); if (!Sync.IsServer || Identity == null) { return; } var character = MyCharacter.CreateCharacter(worldMatrix, velocity, Identity.DisplayName, Identity.Model, Identity.ColorMask, findNearPos: false, useInventory: Id.SerialId == 0, playerSteamId: this.Id.SteamId, botDefinition: botDefinition); if (findFreePlace) { float radius; MyModel model = character.Render.GetModel(); radius = model.BoundingBox.Size.Length() / 2; const float SPHERE_REDUCTION_RATE = 0.9f; radius *= SPHERE_REDUCTION_RATE; // Offset from bottom position to center. Vector3 up = worldMatrix.Up; up.Normalize(); const float RISE_STEP = 0.01f; // 1cm Vector3 offset = up * (radius + RISE_STEP); MatrixD matrix = worldMatrix; matrix.Translation = worldMatrix.Translation + offset; // Attempt first to rotate around the given spawn location (matrix.Up axis rotation) // NOTE: A proper orbital search would be better here Vector3D?correctedPos = MyEntities.FindFreePlace(ref matrix, matrix.GetDirectionVector(Base6Directions.Direction.Up), radius, 200, 15, 0.2f); if (!correctedPos.HasValue) { // Attempt secondly to rotate around matrix.Right axis correctedPos = MyEntities.FindFreePlace(ref matrix, matrix.GetDirectionVector(Base6Directions.Direction.Right), radius, 200, 15, 0.2f); if (!correctedPos.HasValue) { // If everything fails attempt the old FindFreePlace correctedPos = MyEntities.FindFreePlace(worldMatrix.Translation + offset, radius, 200, 15, 0.2f); } } if (correctedPos.HasValue) { worldMatrix.Translation = correctedPos.Value - offset; character.PositionComp.SetWorldMatrix(worldMatrix); } } Sync.Players.SetPlayerCharacter(this, character, spawnedBy); Sync.Players.RevivePlayer(this); }
public static void GetSpawnPosition(float collisionRadius, out Vector3 direction, out Vector3D position) { float distance = 0; foreach (var entity in MyEntities.GetEntities()) { // Include only voxels if (entity is MyVoxelMap) { distance = (float)MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius); } } // 500 - 650m from last voxel distance += MyUtils.GetRandomFloat(500, 650); if (MyEntities.IsWorldLimited()) { distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent()); } else { distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds } direction = MyUtils.GetRandomVector3Normalized(); var searchPosition = MyEntities.FindFreePlace((Vector3D)(direction * distance), collisionRadius); if (!searchPosition.HasValue) { searchPosition = (Vector3D)(direction * distance); // Spawn in existing place (better than crash) } Vector3D globalPoint = (Vector3D)searchPosition; position = globalPoint; if (MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint) != null && MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint).Length() != 0) { MyPlanet planet = MyGravityProviderSystem.GetStrongestGravityWell(globalPoint); double multiplier = planet.MaximumRadius / globalPoint.Length(); globalPoint *= multiplier; Vector3D closestPoint = planet.GetClosestSurfacePointGlobal(ref globalPoint) * 1.25; searchPosition = MyEntities.FindFreePlace(closestPoint, collisionRadius); if (searchPosition.HasValue) { position = searchPosition.Value; } } else { position = searchPosition.Value; } }
private Vector3D?FindPastePosition(Vector3D Target) { BoundingSphereD sphere = FindBoundingSphere(_grids); sphere.Center = Target; /* * Now we know the radius that can house all grids which will now be * used to determine the perfect place to paste the grids to. */ return(MyEntities.FindFreePlace(sphere.Center, (float)sphere.Radius, 60, 8, 1.5f)); }
static void GetAvailableMedicalRooms(long playerId, List <MyMedicalRoomInfo> medicalRooms) { List <MyCubeGrid> cubeGrids = MyEntities.GetEntities().OfType <MyCubeGrid>().ToList(); foreach (var grid in cubeGrids) { grid.GridSystems.UpdatePower(); foreach (var slimBlock in grid.GetBlocks()) { MyMedicalRoom medicalRoom = slimBlock.FatBlock as MyMedicalRoom; if (medicalRoom != null) { medicalRoom.UpdateIsWorking(); if (medicalRoom.IsWorking) { if (medicalRoom.HasPlayerAccess(playerId) || medicalRoom.SetFactionToSpawnee) { MyMedicalRoomInfo info = new MyMedicalRoomInfo(); info.MedicalRoomId = medicalRoom.EntityId; info.MedicalRoomName = medicalRoom.CustomName != null?medicalRoom.CustomName.ToString() : (medicalRoom.Name != null ? medicalRoom.Name : medicalRoom.ToString()); info.OxygenLevel = medicalRoom.GetOxygenLevel(); info.OwnerId = medicalRoom.IDModule.Owner; Vector3D medRoomPosition = medicalRoom.PositionComp.GetPosition(); Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20; Vector3D?cameraPosition = MyEntities.FindFreePlace(preferredCameraPosition, 1); if (!cameraPosition.HasValue) { cameraPosition = preferredCameraPosition; } info.PrefferedCameraPosition = cameraPosition.Value; info.MedicalRoomPosition = medRoomPosition; info.MedicalRoomUp = medicalRoom.PositionComp.WorldMatrix.Up; if (medicalRoom.CubeGrid.Physics != null) { info.MedicalRoomVelocity = medicalRoom.CubeGrid.Physics.LinearVelocity; } medicalRooms.Add(info); } } } } } }
private Vector3D?FindPastePosition(MyObjectBuilder_CubeGrid[] grids, Vector3D pos, string playername) { var player = utils.GetPlayerByNameOrId(playername); Vector3?vector = null; float radius = 0F; foreach (var grid in grids) { var gridSphere = grid.CalculateBoundingSphere(); /* If this is the first run, we use the center of that grid, and its radius as it is */ if (vector == null) { vector = gridSphere.Center; radius = gridSphere.Radius; continue; } /* * If its not the first run, we use the vector we already have and * figure out how far it is away from the center of the subgrids sphere. */ float distance = Vector3.Distance(vector.Value, gridSphere.Center); /* * Now we figure out how big our new radius must be to house both grids * so the distance between the center points + the radius of our subgrid. */ float newRadius = distance + gridSphere.Radius; /* * If the new radius is bigger than our old one we use that, otherwise the subgrid * is contained in the other grid and therefore no need to make it bigger. */ if (newRadius > radius) { radius = newRadius; } } /* * Now we know the radius that can house all grids which will now be * used to determine the perfect place to paste the grids to. */ return(MyEntities.FindFreePlace(player.GetPosition(), radius)); }
public void Teleport(string entityToMove, string destination) { IMyEntity destEntity; if (string.IsNullOrEmpty(destination)) { destEntity = Context.Player?.Controller.ControlledEntity.Entity; } else { Utilities.TryGetEntityByNameOrId(destination, out destEntity); } if (destEntity == null) { Context.Respond("Destination entity not found"); return; } IMyEntity targetEntity; if (string.IsNullOrEmpty(entityToMove)) { targetEntity = Context.Player?.Controller.ControlledEntity.Entity; } else { Utilities.TryGetEntityByNameOrId(entityToMove, out targetEntity); } if (targetEntity == null) { Context.Respond("Target entity not found."); return; } var targetPos = MyEntities.FindFreePlace(destEntity.GetPosition(), (float)targetEntity.WorldAABB.Extents.Max()); if (targetPos == null) { Context.Respond("No free place to teleport."); return; } targetEntity.SetPosition(targetPos.Value); }
private static void spawnBarbarian(Vector3D position) { var newPos = MyEntities.FindFreePlace(position, 1f, 200, 5, 5f); if (!newPos.HasValue) { return; } var botPosition = newPos.Value; var botDefinition = (MyAgentDefinition)MyDefinitionManager.Get <MyBotDefinition>(barbarianId); var createdEntity = MySession.Static.Scene.CreateEntity(botDefinition.BotEntity); createdEntity.PositionComp.SetWorldMatrix(MatrixD.CreateWorld(botPosition)); botDefinition.RaiseBeforeBotSpawned(createdEntity); MySession.Static.Scene.ActivateEntity(createdEntity); botDefinition.AfterBotSpawned(createdEntity); }
public void Import(string gridName, string targetName = null) { Directory.CreateDirectory("ExportedGrids"); if (targetName == null) { if (Context.Player == null) { Context.Respond("Target entity must be specified."); return; } targetName = Context.Player.Controller.ControlledEntity.Entity.DisplayName; } if (!Utilities.TryGetEntityByNameOrId(targetName, out var ent)) { Context.Respond("Target entity not found."); return; } var path = string.Format(ExportPath, gridName); if (!File.Exists(path)) { Context.Respond("File does not exist."); return; } if (MyObjectBuilderSerializer.DeserializeXML(path, out MyObjectBuilder_CubeGrid grid)) { Context.Respond($"Importing grid from {path}"); MyEntities.RemapObjectBuilder(grid); var pos = MyEntities.FindFreePlace(ent.GetPosition(), grid.CalculateBoundingSphere().Radius); if (pos == null) { Context.Respond("No free place."); return; } var x = grid.PositionAndOrientation ?? new MyPositionAndOrientation(); x.Position = pos.Value; grid.PositionAndOrientation = x; MyEntities.CreateFromObjectBuilderParallel(grid, true); } }
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); }
void CircleGps(bool reset, bool forward) { if (MySession.Static != null && MySession.Static.Gpss != null && MySession.Static.LocalHumanPlayer != null) { if (forward) { m_currentGpsIndex--; } else { m_currentGpsIndex++; } m_gpsList.Clear(); MySession.Static.Gpss.GetGpsList(MySession.Static.LocalPlayerId, m_gpsList); if (m_gpsList.Count == 0) { m_currentGpsIndex = 0; return; } if (m_currentGpsIndex < 0) { m_currentGpsIndex = m_gpsList.Count - 1; } if (m_gpsList.Count <= m_currentGpsIndex || reset) { m_currentGpsIndex = 0; } Vector3D gpsPosition = m_gpsList[m_currentGpsIndex].Coords; MySession.Static.SetCameraController(MyCameraControllerEnum.Spectator); Vector3D?cameraPosition = MyEntities.FindFreePlace(gpsPosition + Vector3D.One, 2.0f, 30); MySpectatorCameraController.Static.Position = cameraPosition.HasValue ? cameraPosition.Value : (gpsPosition + Vector3D.One); MySpectatorCameraController.Static.Target = gpsPosition; } }
/// <summary> /// Returns a position adjusted for planets that should be safe to spawn at given the radius and position. /// </summary> /// <param name="collisionRadius">The radius of the object that is trying to spawn.</param> /// <param name="position">The position the object would like to spawn at.</param> /// <param name="forward">(Out) The forward vector the object should spawn with.</param> /// <param name="up">(Out) The up vector the object should spawn with.</param> /// <param name="planetAtmosphereRatio">The ratio within the planet's max radius and atmosphere radius you are positioned in.</param> /// <param name="randomRangeMin">The minimum randomized distance that is added.</param> /// <param name="randomRangeMax">The minimum randomized distance that is added.</param> private static void GetSpawnPositionNearPlanet(MyPlanet planet, float collisionRadius, ref Vector3D position, out Vector3D forward, out Vector3D up, float planetAtmosphereRatio = 0.3f, float randomRangeMin = 500, float randomRangeMax = 650) { // Position us at a desirable height on the planet // Roughl halfway the planet's upper atmosphere and outer radius float randomHeightAdjustment = MyUtils.GetRandomFloat(randomRangeMin, randomRangeMax); float height = planet.MaximumRadius + planetAtmosphereRatio * (planet.AtmosphereRadius - planet.MaximumRadius) + randomHeightAdjustment; // Compute random position position = planet.PositionComp.WorldVolume.Center + MyUtils.GetRandomVector3Normalized() * height; Vector3D?freePlace = MyEntities.FindFreePlace(position, collisionRadius); int numAttempts = 1; // While we have no valid spawn position, try again 3 more times while (!freePlace.HasValue && numAttempts <= 3) { position = planet.PositionComp.WorldVolume.Center + MyUtils.GetRandomVector3Normalized() * height; freePlace = MyEntities.FindFreePlace(position, collisionRadius); numAttempts += 1; } // If we have a valid position, use it if (freePlace.HasValue) { position = freePlace.Value; } // Return orientation perpendicular to planet surface Vector3 gravityAtPosition = MyGravityProviderSystem.CalculateNaturalGravityInPoint(position); if (Vector3.IsZero(gravityAtPosition)) // If we are somehow randomized outside of gravity range, make sure some orientation is used { gravityAtPosition = Vector3.Up; } Vector3D normalizedGravityVector = Vector3D.Normalize(gravityAtPosition); forward = Vector3.CalculatePerpendicularVector(-normalizedGravityVector); up = -normalizedGravityVector; }
public void SpawnAt(MatrixD worldMatrix, Vector3 velocity, bool findFreePlace = true) { Debug.Assert(Sync.IsServer, "Spawning can be called only on the server!"); Debug.Assert(Identity != null, "Spawning with empty identity!"); if (!Sync.IsServer || Identity == null) { return; } if (findFreePlace) { Vector3D?correctedPos = MyEntities.FindFreePlace(worldMatrix.Translation, 0.5f, 200); if (correctedPos.HasValue) { worldMatrix.Translation = correctedPos.Value; } } var character = MyCharacter.CreateCharacter(worldMatrix, velocity, Identity.DisplayName, Identity.Model, Identity.ColorMask, findNearPos: false, useInventory: Id.SerialId == 0); Sync.Players.SetPlayerCharacter(this, character); Sync.Players.RevivePlayer(this); }
// /admin movefrom x y z x y z radius public override bool HandleCommand(ulong userId, string[] words) { if (words.Count() < 2) { Communication.SendPrivateInformation(userId, GetHelp()); return(true); } string sourceName = words[0]; float distance = 50f; // TODO Allow quotes so we can do distance? bool parse = false; if (words.Count() > 2) { parse = float.TryParse(words[words.Count() - 1], out distance); } string targetName; if (parse) { targetName = string.Join(" ", words.Skip(1).Take(words.Count() - 2).ToArray()); } else { targetName = string.Join(" ", words.Skip(1).ToArray()); } Communication.SendPrivateInformation(userId, $"Moving {sourceName} to within {distance}m of {targetName}."); Vector3D position; MyEntity entity = (MyEntity)Player.FindControlledEntity(targetName); if (entity == null) { entity = CubeGrids.Find(targetName); if (entity == null) { Communication.SendPrivateInformation(userId, $"Can not find user or grid with the name: {targetName}"); return(true); } position = entity.PositionComp.GetPosition(); } else { position = entity.PositionComp.GetPosition(); } MyEntity gridToMove = CubeGrids.Find(sourceName); if (gridToMove == null) { Communication.SendPrivateInformation(userId, $"Unable to find: {sourceName}"); return(true); } Vector3D?testPos = null; Wrapper.GameAction(() => testPos = MyEntities.FindFreePlace(position, (float)gridToMove.PositionComp.WorldAABB.Extents.Max( ) + distance)); if (testPos == null) { Communication.SendPrivateInformation(userId, $"Could not find valid location to move: {sourceName}. Try increasing distance."); return(true); } Wrapper.GameAction(() => gridToMove.PositionComp.SetPosition(testPos.Value)); Communication.SendPrivateInformation(userId, $"Moved {sourceName} to within {(int)Math.Round( Vector3D.Distance(testPos.Value, position ) )}m of {targetName}"); return(true); }
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; //GR: Added simple check so burrowing (and Teleport) functions should happen only when on Voxel physics. //Not sure though if this check should be somewhere else (e.g. behaviour Tree) //Check position of Teleport if is clear var resultOnTeleportPos = Sandbox.Engine.Physics.MyPhysics.CastRay(pos + 3 * Bot.AgentEntity.WorldMatrix.Up, pos - 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer); if (resultOnTeleportPos != null) { return(MyBehaviorTreeState.NOT_TICKED); } //GR: Also check current position of spider if on CubeGrid do not teleport var resultOnSpiderPos = Sandbox.Engine.Physics.MyPhysics.CastRay(Bot.AgentEntity.WorldMatrix.Translation - 3 * Bot.AgentEntity.WorldMatrix.Up, Bot.AgentEntity.WorldMatrix.Translation + 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer); if (resultOnSpiderPos != null && (resultOnSpiderPos as VRage.Game.ModAPI.IHitInfo).HitEntity != Bot.AgentEntity) { resultOnSpiderPos = Sandbox.Engine.Physics.MyPhysics.CastRay(Bot.AgentEntity.WorldMatrix.Translation - 3 * Bot.AgentEntity.WorldMatrix.Up, Bot.AgentEntity.WorldMatrix.Translation + 3 * Bot.AgentEntity.WorldMatrix.Up, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.NoVoxelCollisionLayer); return(MyBehaviorTreeState.NOT_TICKED); } float radius = (float)Bot.AgentEntity.PositionComp.WorldVolume.Radius; var planet = MyGamePruningStructure.GetClosestPlanet(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); }
public bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition) { MyPlayer player = Sync.Players.TryGetPlayerById(playerId); bool spawnAsNewPlayer = newIdentity || player == null; Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!"); if (!MySessionComponentMissionTriggers.CanRespawn(playerId)) { return(false); } Vector3D currentPosition = Vector3D.Zero; if (player != null && player.Character != null) { currentPosition = player.Character.PositionComp.GetPosition(); } if (TryFindCryoChamberCharacter(player)) { //Player found in chamber; return(true); } if (!spawnAsNewPlayer) { // Find medical room to spawn at MyMedicalRoom medicalRoom = null; if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI) { List <MyMedicalRoom> medRooms = new List <MyMedicalRoom>(); medicalRoom = GetNearestMedRoom(currentPosition, out medRooms, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId); if (joinGame && medRooms.Count > 0) { medicalRoom = medRooms[MyRandom.Instance.Next(0, medRooms.Count)]; } } else { medicalRoom = FindRespawnMedicalRoom(medicalRoomId, player); if (medicalRoom == null) { return(false); } } // If spawning in medical room fails, we will spawn as a new player if (medicalRoom != null) { SpawnInMedicalRoom(player, medicalRoom, joinGame); } else { spawnAsNewPlayer = true; } } if (spawnAsNewPlayer) { bool resetIdentity = MySession.Static.Settings.PermanentDeath.Value; if (player == null) { var identity = Sync.Players.CreateNewIdentity(player.DisplayName); player = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName); resetIdentity = false; } if (MySession.Static.CreativeMode) { Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 1, 200); if (correctedPos.HasValue) { currentPosition = correctedPos.Value; } player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero); } else { SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity); } } return(true); }
VRageMath.Vector3D?IMyEntities.FindFreePlace(VRageMath.Vector3D basePos, float radius, int maxTestCount, int testsPerDistance, float stepSize) { return(MyEntities.FindFreePlace(basePos, radius, maxTestCount, testsPerDistance, stepSize)); }
private void UpdateDroneSpawning() { int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; m_iteratingAntennas = true; foreach (var antennaEntry in m_pirateAntennas) { PirateAntennaInfo antennaInfo = antennaEntry.Value; if (!antennaInfo.IsActive) { continue; } if (currentTime - antennaInfo.LastGenerationGameTime <= antennaInfo.AntennaDefinition.SpawnTimeMs) { continue; } MyRadioAntenna antenna = null; MyEntities.TryGetEntityById(antennaEntry.Key, out antenna); Debug.Assert(antenna != null, "Could not find antenna for spawning enemy drones!"); if (antennaInfo.AntennaDefinition.SpawnGroupSampler == null) { return; } var spawnGroup = antennaInfo.AntennaDefinition.SpawnGroupSampler.Sample(); Debug.Assert(spawnGroup != null, "Could not find spawnGroup for spawning enemy drones!"); if ( !MySession.Static.Settings.EnableDrones || antennaInfo.SpawnedDrones >= antennaInfo.AntennaDefinition.MaxDrones || antenna == null || spawnGroup == null || (m_droneInfos.Reader.Count() >= MySession.Static.Settings.MaxDrones) ) { antennaInfo.LastGenerationGameTime = currentTime; continue; } spawnGroup.ReloadPrefabs(); BoundingSphereD antennaSphere = new BoundingSphereD(antenna.WorldMatrix.Translation, antenna.GetRadius()); var players = MySession.Static.Players.GetOnlinePlayers(); bool successfulSpawn = false; foreach (var player in players) { if (antennaSphere.Contains(player.GetPosition()) == ContainmentType.Contains) { Vector3D?spawnPosition = null; for (int i = 0; i < 10; ++i) { Vector3D position = antenna.WorldMatrix.Translation + MyUtils.GetRandomVector3Normalized() * antennaInfo.AntennaDefinition.SpawnDistance; spawnPosition = MyEntities.FindFreePlace(position, spawnGroup.SpawnRadius); if (spawnPosition.HasValue) { break; } } successfulSpawn = SpawnDrone(antenna, antenna.OwnerId, spawnPosition.Value, spawnGroup); break; } } // Don't reschedule if there was no player inside if (successfulSpawn) { antennaInfo.LastGenerationGameTime = currentTime; } } m_pirateAntennas.ApplyChanges(); m_iteratingAntennas = false; }
public override bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition, VRage.ObjectBuilders.SerializableDefinitionId?botDefinitionId) { MyPlayer player = Sync.Players.GetPlayerById(playerId); bool spawnAsNewPlayer = newIdentity || player == null; Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!"); if (!MySessionComponentMissionTriggers.CanRespawn(playerId)) { return(false); } Vector3D currentPosition = Vector3D.Zero; if (player != null && player.Character != null) { currentPosition = player.Character.PositionComp.GetPosition(); } if (TryFindCryoChamberCharacter(player)) { //Player found in chamber; return(true); } MyBotDefinition botDefinition = null; if (botDefinitionId != null) { MyDefinitionManager.Static.TryGetBotDefinition((MyDefinitionId)botDefinitionId, out botDefinition); } if (!spawnAsNewPlayer) { if (respawnShipId != null) { SpawnAtShip(player, respawnShipId, botDefinition); return(true); } if (spawnPosition.HasValue) { Vector3D gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(spawnPosition.Value); if (Vector3D.IsZero(gravity)) { gravity = Vector3D.Down; } else { gravity.Normalize(); } Vector3D perpendicular; gravity.CalculatePerpendicularVector(out perpendicular); player.SpawnAt(MatrixD.CreateWorld(spawnPosition.Value, perpendicular, -gravity), Vector3.Zero, null, botDefinition, true); return(true); } // Find respawn block to spawn at MyRespawnComponent foundRespawn = null; if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI) { List <MyRespawnComponent> respawns = null; var nearestRespawn = GetNearestRespawn(currentPosition, out respawns, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId); if (joinGame && respawns.Count > 0) { foundRespawn = respawns[MyRandom.Instance.Next(0, respawns.Count)]; } } else { foundRespawn = FindRespawnById(medicalRoomId, player); if (foundRespawn == null) { return(false); } } // If spawning in respawn block fails, we will spawn as a new player if (foundRespawn != null) { SpawnInRespawn(player, foundRespawn, botDefinition); } else { spawnAsNewPlayer = true; } } if (spawnAsNewPlayer) { bool resetIdentity = false; if (MySession.Static.Settings.PermanentDeath.Value) { var oldIdentity = Sync.Players.TryGetPlayerIdentity(playerId); resetIdentity = oldIdentity.FirstSpawnDone; } if (player == null) { var identity = Sync.Players.CreateNewIdentity(player.DisplayName); player = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName); resetIdentity = false; } if (MySession.Static.CreativeMode) { Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 2, 200); if (correctedPos.HasValue) { currentPosition = correctedPos.Value; } player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero, null, botDefinition); } else { SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity, botDefinition); } } return(true); }
public static void OnGlobalSpawnEvent(object senderEvent) { // Select a spawn group to spawn MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup(); if (spawnGroup == null) { return; } spawnGroup.ReloadPrefabs(); ProfilerShort.Begin("Generate position and direction"); double spawnDistance = NEUTRAL_SHIP_SPAWN_DISTANCE; Vector3D playerPosition = Vector3D.Zero; bool isWorldLimited = MyEntities.IsWorldLimited(); int numPlayers = 0; if (isWorldLimited) { spawnDistance = Math.Min(spawnDistance, MyEntities.WorldSafeHalfExtent() - spawnGroup.SpawnRadius); } else { // In infinite worlds players can be thousands of kilometers away, so spawn ship around random player // so cargo ships will be spawned around every player at some time var players = MySession.Static.Players.GetOnlinePlayers(); // In DS there can be no players connected numPlayers = Math.Max(0, players.Count - 1); int randomPlayerPosition = MyUtils.GetRandomInt(0, numPlayers); int i = 0; foreach (var player in players) { if (i == randomPlayerPosition) { if (player.Character != null) { playerPosition = player.GetPosition(); } break; } i++; } } if (spawnDistance < 0.0f) { MySandboxGame.Log.WriteLine("Not enough space in the world to spawn such a huge spawn group!"); return; } double forbiddenRadius = NEUTRAL_SHIP_FORBIDDEN_RADIUS; BoundingBoxD spawnBox; if (isWorldLimited) { spawnBox = new BoundingBoxD(new Vector3D(playerPosition - spawnDistance), new Vector3D(playerPosition + spawnDistance)); } else { // We need to extend bouding box so cargo ships aren't spawned near other players GetSafeBoundingBoxForPlayers(playerPosition, spawnDistance, out spawnBox); // Forbidden radius is sphere around all players in box. // Bounding box is generated from players positions so their distance to center shall be same for all players forbiddenRadius += spawnBox.HalfExtents.Max() - NEUTRAL_SHIP_FORBIDDEN_RADIUS; } // Get the direction to the center and deviate it randomly Vector3D?origin = MyUtils.GetRandomBorderPosition(ref spawnBox); origin = MyEntities.FindFreePlace(origin.Value, spawnGroup.SpawnRadius); if (!origin.HasValue) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships - no free place found"); MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } // Radius in arc units of the forbidden sphere in the center, when viewed from origin float centerArcRadius = (float)Math.Atan(forbiddenRadius / (origin.Value - spawnBox.Center).Length()); // Generate direction with elevation from centerArcRadius radians to (cAR + N_S_D_S) radians Vector3D direction = -Vector3D.Normalize(origin.Value); float theta = MyUtils.GetRandomFloat(centerArcRadius, centerArcRadius + NEUTRAL_SHIP_DIRECTION_SPREAD); float phi = MyUtils.GetRandomRadian(); Vector3D cosVec = Vector3D.CalculatePerpendicularVector(direction); Vector3D sinVec = Vector3D.Cross(direction, cosVec); cosVec *= (Math.Sin(theta) * Math.Cos(phi)); sinVec *= (Math.Sin(theta) * Math.Sin(phi)); direction = direction * Math.Cos(theta) + cosVec + sinVec; Vector3D destination = Vector3D.Zero; RayD ray = new RayD(origin.Value, direction); double? intersection = ray.Intersects(spawnBox); Vector3D directionMult; if (!intersection.HasValue || intersection.Value < NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH) { directionMult = direction * NEUTRAL_SHIP_MINIMAL_ROUTE_LENGTH; } else { directionMult = direction * intersection.Value; } destination = origin.Value + directionMult; Vector3D upVector = Vector3D.CalculatePerpendicularVector(direction); Vector3D rightVector = Vector3D.Cross(direction, upVector); MatrixD originMatrix = MatrixD.CreateWorld(origin.Value, direction, upVector); ProfilerShort.End(); ProfilerShort.Begin("Check free space"); // CH:TODO: Convex cast to detect collision // Check ships' path to avoid possible collisions. (TODO: But only if it is said in the definitions) m_raycastHits.Clear(); foreach (var shipPrefab in spawnGroup.Prefabs) { var prefabDef = MyDefinitionManager.Static.GetPrefabDefinition(shipPrefab.SubtypeId); Debug.Assert(prefabDef != null); Vector3D shipPosition = Vector3.Transform(shipPrefab.Position, originMatrix); Vector3D shipDestination = shipPosition + directionMult; float radius = prefabDef == null ? 10.0f : prefabDef.BoundingSphere.Radius; MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer); if (m_raycastHits.Count() > 0) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision"); MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } for (int i = 0; i < 4; ++i) { Vector3D shiftVector = upVector * m_upVecMultipliers[i] * radius + rightVector * m_rightVecMultipliers[i] * radius; MyPhysics.CastRay(shipPosition + shiftVector, shipDestination + shiftVector, m_raycastHits, MyPhysics.ObjectDetectionCollisionLayer); if (m_raycastHits.Count() > 0) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships due to collision"); MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } } } ProfilerShort.End(); ProfilerShort.Begin("Spawn ships"); //This is not an NPC so that it doesn't show up in assign ownership drop down menu MyIdentity spawnGroupIdentity = Sync.Players.CreateNewIdentity("Neutral NPC"); long spawnGroupId = spawnGroupIdentity.IdentityId; // The ships were collision-free. Now spawn them foreach (var shipPrefab in spawnGroup.Prefabs) { ProfilerShort.Begin(shipPrefab.BeaconText); // Yes, this could have been saved in the previous loop, but compared to (e.g.) raycasts, this does not take too much time to recalculate Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix); Vector3D shipDestination = shipPosition + directionMult; Vector3D up = Vector3D.CalculatePerpendicularVector(-direction); m_tmpGridList.Clear(); // Deploy ship ProfilerShort.Begin("Spawn cargo ship"); MyPrefabManager.Static.SpawnPrefab( resultList: m_tmpGridList, prefabName: shipPrefab.SubtypeId, position: shipPosition, forward: direction, up: up, initialLinearVelocity: shipPrefab.Speed * direction, beaconName: shipPrefab.BeaconText, spawningOptions: Sandbox.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection | Sandbox.ModAPI.SpawningOptions.SpawnRandomCargo | Sandbox.ModAPI.SpawningOptions.DisableDampeners, updateSync: true); ProfilerShort.End(); foreach (var grid in m_tmpGridList) { grid.ChangeGridOwnership(spawnGroupId, MyOwnershipShareModeEnum.None); var cockpit = grid.GetFirstBlockOfType <MyCockpit>(); if (cockpit != null) { MySimpleAutopilot ai = new MySimpleAutopilot(shipDestination, (Vector3)direction); cockpit.AttachAutopilot(ai); break; } } m_tmpGridList.Clear(); ProfilerShort.End(); } ProfilerShort.End(); }
internal void ChangeSlotInternal(EquiPlayerAttachmentComponent.Slot slot, float randSeed) { this.GetLogger().Debug($"Changing slot for {Entity} to {slot?.Controllable?.Entity}#{slot?.Definition.Name}"); var old = _controlledSlot; _controlledSlot = slot; var oldAnimData = old?.Definition.ByIndex(_saveData.AnimationId); EquiPlayerAttachmentComponentDefinition.AnimationDesc?newAnimData = null; if (slot != null && _saveData.ControlledSlot == slot.Definition.Name) { newAnimData = slot.Definition.ByIndex(_saveData.AnimationId); } if (!newAnimData.HasValue) { newAnimData = slot?.Definition.SelectAnimation(Entity.DefinitionId ?? default(MyDefinitionId), randSeed, out _saveData.AnimationId); } // Handles animation controller switching var animController = Entity.Components.Get <MyAnimationControllerComponent>(); if (animController != null) { if (oldAnimData.HasValue) { animController.TriggerAction(oldAnimData.Value.Stop); } if (newAnimData.HasValue) { AddScheduledCallback(CommitAnimationStart); } } // Handle restoring character's position if (slot == null && old?.Controllable?.Entity != null && old.Controllable.Entity.InScene) { var relMatrix = _saveData.RelativeOrientation.GetMatrix(); if (relMatrix.Scale.AbsMax() < 1) { relMatrix = MatrixD.Identity; } var outPos = relMatrix * old.AttachMatrix; var transformedCenter = Vector3.TransformNormal(Entity.PositionComp.LocalAABB.Center, outPos); var orientation = Quaternion.CreateFromRotationMatrix(Entity.PositionComp.WorldMatrix.GetOrientation()); var halfExtents = Entity.PositionComp.LocalAABB.HalfExtents; halfExtents.X *= 0.25f; halfExtents.Z *= 0.25f; var translate = MyEntities.FindFreePlace(outPos.Translation + transformedCenter, orientation, halfExtents, 200, 20, 0.1f, false); if (translate.HasValue) { outPos.Translation = translate.Value - transformedCenter; } else { outPos = old.AttachMatrix; } var gravity = Vector3.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(outPos.Translation)); if (MyAPIGateway.Physics.CastRay(outPos.Translation - gravity, outPos.Translation + 10 * gravity, out var hit)) { outPos.Translation = hit.Position; } Entity.PositionComp.SetWorldMatrix(outPos, Entity.Parent, true); } // Handles storing the character's position when attaching if (slot != null) { _saveData.RelativeOrientation = new MyPositionAndOrientation(MatrixD.Normalize(Entity.WorldMatrix * MatrixD.Invert(slot.AttachMatrix))); } // Handle keeping the physics in check if (Entity.Physics != null) { var wantsPhysicsEnabled = slot == null; if (wantsPhysicsEnabled && !Entity.Physics.Enabled) { Entity.Physics.Activate(); } else if (!wantsPhysicsEnabled && Entity.Physics.Enabled) { Entity.Physics.Deactivate(); } if (slot == null) { var oldPhys = old?.Controllable?.Entity.ParentedPhysics(); if (oldPhys != null) { Entity.Physics.LinearVelocity = oldPhys.GetVelocityAtPoint(old.Controllable.Entity.WorldMatrix.Translation); } } } _saveData.ControlledEntity = slot?.Controllable.Entity.EntityId ?? 0; _saveData.ControlledSlot = slot?.Definition.Name; if (slot == null) { _tracker.Unlink(Entity.EntityId); } else { _tracker.Link(Entity.EntityId, new ControlledId(slot)); } if (old?.Controllable != null) { RemoveFixedUpdate(FixPosition); } if (slot?.Controllable != null) { AddFixedUpdate(FixPosition, PriorityOverride); } FixPosition(); if (old != null) { old.AttachedCharacter = null; } if (slot != null) { slot.AttachedCharacter = Entity; } ControlledChanged?.Invoke(this, old, slot); _tracker.RaiseControlledChange(this, old, slot); }
public override bool Update(bool hasFocus) { /*if (m_respawnsTable.RowsCount == 0 && State != MyGuiScreenState.CLOSING && MySession.Static.LocalHumanPlayer != null) * { * MyPlayerCollection.RespawnRequest(joinGame: true, newPlayer: true, medicalId: 0, shipPrefabId: null); * CloseScreen(); * }*/ UpdateSpawnShipTimes(); bool retval = base.Update(hasFocus); if (m_selectedRespawnShip != null) { var rc = MySpaceRespawnComponent.Static; int cooldown = rc.GetRespawnCooldownSeconds(MySession.Static.LocalHumanPlayer.Id, m_selectedRespawnShip.Id.SubtypeName); if (rc.IsSynced && cooldown == 0) { RespawnShipImmediately(m_selectedRespawnShip.Id.SubtypeName); } } if (m_respawnsTable.RowsCount == 0) { RefreshRespawnPoints();//because medical rooms are not powered when the map starts } if (m_respawnsTable.SelectedRow != null && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity) { MyMedicalRoomInfo userData = m_respawnsTable.SelectedRow.UserData as MyMedicalRoomInfo; if (userData != null) { m_respawnButton.Enabled = false; MyMedicalRoom medicalRoom; if (MyEntities.TryGetEntityById <MyMedicalRoom>(userData.MedicalRoomId, out medicalRoom)) { m_respawnButton.Enabled = true; Vector3D medRoomPosition = (Vector3D)medicalRoom.PositionComp.GetPosition(); Vector3D preferredCameraPosition = medRoomPosition + medicalRoom.WorldMatrix.Up * 20 + medicalRoom.WorldMatrix.Right * 20 + medicalRoom.WorldMatrix.Forward * 20; Vector3D?cameraPosition = MyEntities.FindFreePlace(preferredCameraPosition, 1); if (!cameraPosition.HasValue) { cameraPosition = preferredCameraPosition; } MySession.Static.SetCameraController(MyCameraControllerEnum.Spectator, null, cameraPosition.Value); MySpectatorCameraController.Static.Target = medRoomPosition; } } } if (m_labelNoRespawn.Text == null) { m_labelNoRespawn.Visible = false; } else { m_labelNoRespawn.Visible = true; } return(retval); }
public override void Execute(Data.Data data, Dictionary <string, object> parameters) { SessionHandler.EnqueueAction(() => { var player = Utils.GetPlayer(); if (player != null) { var id = new MyDefinitionId((MyObjectBuilderType)typeof(MyObjectBuilder_RadioAntenna), "SmallBlockRadioAntenna"); var up = player.Character.PositionComp.GetOrientation().Up; up.Normalize(); var definitionBase = (MyRadioAntennaDefinition)MyDefinitionManager.Static.GetCubeBlockDefinition(id); var pos = player.GetPosition() + up * 50; var world = MatrixD.CreateWorld(pos, Vector3.Forward, Vector3.Up); var color = Color.Red.ColorToHSV(); var pirateFaction = MySession.Static.Factions.TryGetFactionByTag("SPRT"); MyCubeBuilder.SpawnDynamicGrid(definitionBase, player.Character, world, color, MyStringHash.NullOrEmpty, 0L, MyCubeBuilder.SpawnFlags.Default | MyCubeBuilder.SpawnFlags.SpawnAsMaster, pirateFaction.FounderId, entity => { var grid = (MyCubeGrid)entity; var pirateAntennas = MySession.Static.GetComponent <MyPirateAntennas>(); if (pirateAntennas != null) { var drones = Utils.IsInSpace(pos) ? Configuration.Plugin.Get(c => c.SpaceDrones): Configuration.Plugin.Get(c => c.PlanetDrones); var drone = (string.IsNullOrEmpty(Drone) ? drones[_random.Next(drones.Length)]: Drone) ?? "Vulture Drone"; MyDefinitionManager.Static.TryGetDefinition( new MyDefinitionId( (MyObjectBuilderType)typeof(MyObjectBuilder_SpawnGroupDefinition), drone), out MySpawnGroupDefinition spawnGroup); if (spawnGroup != null) { Vector3D?nullable = new Vector3D?(); for (int index = 0; index < 10; ++index) { world = entity.WorldMatrix; nullable = MyEntities.FindFreePlace( world.Translation + MyUtils.GetRandomVector3Normalized() * 1500, spawnGroup.SpawnRadius); if (nullable.HasValue) { break; } } foreach (var antenna in grid.GetFatBlocks <MyRadioAntenna>()) { _spawnDrone.Invoke(pirateAntennas, new object[] { antenna, pirateFaction.FounderId, nullable.Value, spawnGroup, new Vector3?(), new Vector3?() }); } var spawns = spawnGroup.Prefabs.Select(prefab => prefab.SubtypeId.ToSplitCase()) .GroupBy(s => s).Select(grouping => (grouping.Count() > 1 ? grouping.Count() + "x " : "") + grouping.Key) .Join(); var msg = "Spawned " + spawns; Utils.SendChat(msg); ActionNotification.SendActionMessage(msg, Color.Red, "ArcHudGPSNotification1"); } } grid.CubeBlocks.ToList().ForEach(block => grid.RemoveBlock(block)); }); } }); }