public double SafeZoneIntersectionCheck(MySafeZone zone) { var zoneEntity = zone as IMyEntity; if (zone.Shape == MySafeZoneShape.Sphere) { var newSphere = new BoundingSphereD(zoneEntity.PositionComp.WorldVolume.Center, zone.Radius); var result = Ray.Intersects(newSphere); if (result.HasValue == true) { return((double)result); } } else { var result = Ray.Intersects(zoneEntity.PositionComp.WorldAABB); if (result.HasValue == true) { return((double)result); } } return(-1); }
public bool HitFriendlyShield(Vector3D weaponPos, Vector3D targetPos, Vector3D dir) { var testRay = new RayD(weaponPos, dir); Comp.Ai.TestShields.Clear(); var checkDistanceSqr = Vector3.DistanceSquared(targetPos, weaponPos); for (int i = 0; i < Comp.Ai.NearByFriendlyShields.Count; i++) { var shield = Comp.Ai.NearByFriendlyShields[i]; var dist = testRay.Intersects(shield.PositionComp.WorldVolume); if (dist != null && dist.Value * dist.Value <= checkDistanceSqr) { Comp.Ai.TestShields.Add(shield); } } if (Comp.Ai.TestShields.Count == 0) { return(false); } var result = Comp.Ai.Session.SApi.IntersectEntToShieldFast(Comp.Ai.TestShields, testRay, true, false, Comp.Ai.AiOwner, checkDistanceSqr); return(result.Item1 && result.Item2 > 0); }
private bool RayCheckTargets(Vector3D origin, Vector3D dir, out MyEntity closestEnt, out Vector3D hitPos, out bool foundOther, bool checkOthers = false) { var ai = _session.TrackingAi; var closestDist = double.MaxValue; closestEnt = null; foreach (var info in ai.Targets.Keys) { var hit = info as MyCubeGrid; if (hit == null) { continue; } var ray = new RayD(origin, dir); var dist = ray.Intersects(info.PositionComp.WorldVolume); if (dist.HasValue) { if (dist.Value < closestDist) { closestDist = dist.Value; closestEnt = hit; } } } foundOther = false; if (checkOthers) { for (int i = 0; i < ai.Obstructions.Count; i++) { var otherEnt = ai.Obstructions[i]; if (otherEnt is MyCubeGrid) { var ray = new RayD(origin, dir); var dist = ray.Intersects(otherEnt.PositionComp.WorldVolume); if (dist.HasValue) { if (dist.Value < closestDist) { closestDist = dist.Value; closestEnt = otherEnt; foundOther = true; } } } } } if (closestDist < double.MaxValue) { hitPos = origin + (dir * closestDist); } else { hitPos = Vector3D.Zero; } return(closestEnt != null); }
private bool HitDoor(HitEntity hitEnt, MyDoorBase door) { var ray = new RayD(ref hitEnt.Intersection.From, ref hitEnt.Intersection.Direction); var rayHit = ray.Intersects(door.PositionComp.WorldVolume); if (rayHit != null) { var hitPos = hitEnt.Intersection.From + (hitEnt.Intersection.Direction * (rayHit.Value + 0.25f)); IHitInfo hitInfo; if (MyAPIGateway.Physics.CastRay(hitPos, hitEnt.Intersection.To, out hitInfo, 15)) { var rotMatrix = Quaternion.CreateFromRotationMatrix(door.WorldMatrix); var obb = new MyOrientedBoundingBoxD(door.PositionComp.WorldAABB.Center, door.PositionComp.LocalAABB.HalfExtents, rotMatrix); var sphere = new BoundingSphereD(hitInfo.Position + (hitEnt.Intersection.Direction * 0.15f), 0.01f); if (obb.Intersects(ref sphere)) { return(true); } } } return(false); }
/// <summary> /// Approaching, going to intersect turretMissileBubble. /// Meteors are also checked, they are after all, essentially missiles. /// </summary> /// <returns></returns> private bool missileIsThreat(IMyEntity missile, out double toP0_lengthSquared, bool allowInside) { toP0_lengthSquared = -1; if (missile.Closed || missile.Physics == null) { return(false); } Vector3D P0 = missile.GetPosition(); if (missile.Physics.LinearVelocity.LengthSquared() < 1) { return(false); } Vector3D missileDirection = Vector3D.Normalize(missile.Physics.LinearVelocity); if (!allowInside) { toP0_lengthSquared = (P0 - turretPosition).LengthSquared(); if (toP0_lengthSquared < turretMissileBubble.Radius * turretMissileBubble.Radius + 25) // missile is inside bubble { return(false); } } RayD missileRay = new RayD(P0, missileDirection); //myLogger.debugLog("missileRay = " + missileRay, "missileIsHostile()"); double?intersects = missileRay.Intersects(turretMissileBubble); if (intersects != null) { //myLogger.debugLog("got a missile intersection of " + intersects, "getBestMissile()"); return(true); } return(false); }
public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable) { const float range = 5000000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; IMyCubeGrid occupiedGrid = null; if (controlledEntity.Entity.Parent == null) { worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); } else { occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid; worldMatrix = controlledEntity.Entity.WorldMatrix; // TODO: need to adjust for position of cockpit within ship. startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f); } var entites = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary <IMyEntity, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); foreach (var entity in entites) { if (findShips || findCubes) { var cubeGrid = entity as IMyCubeGrid; if (cubeGrid != null) { if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId) { continue; } // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste. if (ignoreProjection && cubeGrid.Physics == null) { continue; } // check if the ray comes anywhere near the Grid before continuing. if (ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (hit.HasValue) { var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); var block = cubeGrid.GetCubeBlock(hit.Value); if (block.FatBlock != null && findCubes) { list.Add(block.FatBlock, distance); } else if (findShips) { list.Add(entity, distance); } } } } } if (findPlayers) { var controller = entity as IMyControllableEntity; if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findReplicable) { var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity; if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findAsteroids) { var voxelMap = entity as IMyVoxelMap; if (voxelMap != null) { var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2); var distance = (startPosition - center).Length(); // use distance to center of asteroid. list.Add(entity, distance); } } } if (findPlanets) { // Looks to be working against Git and public release. var planet = entity as Sandbox.Game.Entities.MyPlanet; if (planet != null) { var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = planet.WorldMatrix.Translation; var distance = (startPosition - center).Length(); // use distance to center of planet. list.Add(entity, distance); } } } } if (list.Count == 0) { lookEntity = null; lookDistance = 0; hitPoint = Vector3D.Zero; return; } // find the closest Entity. var item = list.OrderBy(f => f.Value).First(); lookEntity = item.Key; lookDistance = item.Value; hitPoint = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance); }
public override bool Invoke(ulong steamId, long playerId, string messageText) { #region test if (messageText.Equals("/test", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. //MyAPIGateway.Utilities.ShowMessage("path", MyAPIGateway.Session.CurrentPath); //MyAPIGateway.Utilities.ShowMessage("size1", MyAPIGateway.Utilities.ConfigDedicated.SessionSettings.WorldSizeKm.ToString()); //MyAPIGateway.Utilities.ShowMessage("size2", MyAPIGateway.Session.GetWorld().Checkpoint.Settings.WorldSizeKm.ToString()); //IMyConfigDedicated config = null; //List<string> admins = null; try { //config = MyAPIGateway.Utilities.ConfigDedicated; //config.Load(); //config. } catch (Exception) { MyAPIGateway.Utilities.ShowMessage("Exception", "ConfigDedicated"); //ex.Message); } //if (config != null) { try { StringBuilder str = new StringBuilder(); var players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p != null); str.AppendLine("Player Count {0}", players.Count); var identities = new List <IMyIdentity>(); MyAPIGateway.Players.GetAllIdentites(identities); str.AppendLine("Identities Count {0}", identities.Count); //str.AppendLine("Admin Count {0}", config.Administrators.Count); ////str.AppendLine("WorldName {0}", config.WorldName); ////str.AppendLine("WorldSize {0}", config.SessionSettings.WorldSizeKm); //str.AppendLine("Mods Count {0}", config.Mods.Count); ////str.AppendLine("IP {0}", config.IP)); //var clients = MyAPIGateway.Session.GetWorld().Checkpoint.Clients; //str.AppendLine("Client Count", clients == null ? "null" : string.Format("{0}", clients.Count)); //if (clients != null) //{ // var client = clients.FirstOrDefault(c => c.SteamId == MyAPIGateway.Multiplayer.MyId); // if (client != null) // { // str.AppendLine("IsAdmin {0}", client.IsAdmin); // } //} int index = 1; foreach (var identity in identities.OrderBy(i => i.DisplayName)) { var steamPlayer = players.FirstOrDefault(p => p.IdentityId == identity.IdentityId); if (steamPlayer != null) { str.AppendFormat("#{0} {1} {2} '{3}'\r\n", index++, steamPlayer?.PromoteLevel, steamPlayer?.SteamUserId, identity.DisplayName); } } MyAPIGateway.Utilities.ShowMissionScreen("test", null, null, str.ToString()); } catch (Exception ex) { MyAPIGateway.Utilities.ShowMissionScreen("Exception", "reading config", null, ex.ToString()); } } return(true); } #endregion #region test2 if (messageText.Equals("/test2", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. var count = MyAPIGateway.Utilities.ConfigDedicated.Administrators.Count.ToString(CultureInfo.InvariantCulture); MyAPIGateway.Utilities.ShowMessage("Admins", string.Format("Count {0}", count)); MyAPIGateway.Utilities.ShowMessage("Players", string.Format("Count {0}", MyAPIGateway.Players.Count)); MyAPIGateway.Utilities.ShowMessage("MultiPlayers", string.Format("Count {0}", MyAPIGateway.Multiplayer.Players.Count)); return(true); } #endregion #region test3 if (messageText.Equals("/test3", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. StringBuilder msg = new StringBuilder(); msg.AppendFormat("MyId {0}\r\n", MyAPIGateway.Multiplayer.MyId); msg.AppendFormat("SteamId {0}\r\n", MyAPIGateway.Session.Player.SteamUserId); msg.AppendFormat("PlayerID {0}\r\n", MyAPIGateway.Session.Player.IdentityId); msg.AppendFormat("IdentityId {0}\r\n", MyAPIGateway.Session.Player.IdentityId); msg.AppendFormat("MyName {0}\r\n", MyAPIGateway.Multiplayer.MyName); msg.AppendFormat("IsServer {0}\r\n", MyAPIGateway.Multiplayer.IsServer); msg.AppendFormat("ServerId {0}\r\n", MyAPIGateway.Multiplayer.ServerId); msg.AppendFormat("IsServerPlayer {0}\r\n", MyAPIGateway.Multiplayer.IsServerPlayer(MyAPIGateway.Session.Player.Client)); msg.AppendFormat("MultiplayerActive {0}\r\n", MyAPIGateway.Multiplayer.MultiplayerActive); msg.AppendFormat("OnlineMode {0}\r\n", MyAPIGateway.Session.OnlineMode); msg.AppendFormat("IsDedicated {0}\r\n", MyAPIGateway.Utilities.IsDedicated); //msg.AppendFormat("Culture {0}\r\n", MyTexts.Culture.IetfLanguageTag); msg.AppendFormat("Culture {0}\r\n", MyAPIGateway.Session.Config.Language); msg.AppendFormat("Culture {0}-{1}\r\n", MyTexts.Languages[MyAPIGateway.Session.Config.Language].CultureName, MyTexts.Languages[MyAPIGateway.Session.Config.Language].SubcultureName); var languageRu = MyTexts.Languages[MyLanguagesEnum.Russian]; MyTexts.Clear(); MyTexts.LoadTexts(Path.Combine(MyAPIGateway.Utilities.GamePaths.ContentPath, "Data", "Localization"), languageRu.CultureName, languageRu.SubcultureName); var yesRu = MyStringId.Get("DisplayName_Item_GoldIngot").GetString(); var russianGold = MyTexts.GetString(MyStringId.Get("DisplayName_Item_GoldIngot")); var languageEn = MyTexts.Languages[MyLanguagesEnum.English]; MyTexts.Clear(); MyTexts.LoadTexts(Path.Combine(MyAPIGateway.Utilities.GamePaths.ContentPath, "Data", "Localization"), languageEn.CultureName, languageRu.SubcultureName); var yesEn = MyStringId.Get("DisplayName_Item_GoldIngot").GetString(); msg.AppendFormat("Language Test Ru={0} En={1}\r\n", yesRu, yesEn); // CultureInfo has been set to InvariantCulture since 01.100.xxx // CurrentThread is overwritten in MyInitializer to assist in reading Exceptions (which is stupid as stack traces are all in code). So don't bother. //msg.AppendFormat("Culture '{0}' '{1}' '{2}'\r\n", CultureInfo.CurrentUICulture, CultureInfo.CurrentUICulture.IetfLanguageTag, CultureInfo.CurrentUICulture.Name); //msg.AppendFormat("Culture '{0}'\r\n", System.Threading.Thread.CurrentThread.CurrentUICulture.IetfLanguageTag); // not whitelisted anyhow. var ed = ((MyObjectBuilder_EnvironmentDefinition)MyDefinitionManager.Static.EnvironmentDefinition.GetObjectBuilder()); msg.AppendFormat("LargeShipMaxSpeed {0}\r\n", ed.LargeShipMaxSpeed); msg.AppendFormat("LargeShipMaxSpeed {0}\r\n", MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed); msg.AppendFormat("SmallShipMaxSpeed {0}\r\n", MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed); msg.AppendFormat("ViewDistance {0:N}m\r\n", MyAPIGateway.Session.SessionSettings.ViewDistance); msg.AppendFormat("LastSaveTime {0:o}\r\n", MyAPIGateway.Session.GetWorld().Checkpoint.LastSaveTime); MyAPIGateway.Utilities.ShowMissionScreen("test3", null, null, msg.ToString()); return(true); } #endregion #region test4 if (messageText.Equals("/test4", StringComparison.InvariantCultureIgnoreCase)) { var player = MyAPIGateway.Session.Player; if (player != null) { var pos = player.GetPosition(); MyAPIGateway.Utilities.ShowMessage("Player", "pos={0:N},{1:N},{2:N}", pos.X, pos.Y, pos.Z); } var cockpit = MyAPIGateway.Session.ControlledObject as IMyCockpit; var remoteControl = MyAPIGateway.Session.ControlledObject as IMyRemoteControl; var character = MyAPIGateway.Session.ControlledObject as IMyCharacter; //var character2 = MyAPIGateway.Session.ControlledObject as Sandbox.Game.Entities.Character.MyCharacter; var camera = MyAPIGateway.Session.ControlledObject as IMyCamera; var cameraBlock = MyAPIGateway.Session.ControlledObject as IMyCameraBlock; var cameraController = MyAPIGateway.Session.ControlledObject as IMyCameraController; //var spectator = MyAPIGateway.Session.ControlledObject as VRage.MySpectator; var spectator = MyAPIGateway.Session.Camera; if (cockpit != null) { MyAPIGateway.Utilities.ShowMessage("Control", "in cockpit."); } if (remoteControl != null) { MyAPIGateway.Utilities.ShowMessage("Control", "remoting."); } if (character != null) { MyAPIGateway.Utilities.ShowMessage("Control", "character."); } //if (character2 != null) //{ // //var pos = character2.PositionComp.GetPosition(); // Uses MyEntity which is not whitelisted. // MyAPIGateway.Utilities.ShowMessage("Control", "character2."); //} if (camera != null) { MyAPIGateway.Utilities.ShowMessage("Control", "camera."); } if (cameraBlock != null) { MyAPIGateway.Utilities.ShowMessage("Control", "camera block."); } if (cameraController != null) { //var pos = cameraController.GetViewMatrix().Translation; //MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. FPV={0} POS={1:N},{2:N},{3:N}", cameraController.IsInFirstPersonView, pos.X, pos.Y, pos.Z); } if (MyAPIGateway.Session.ControlledObject.Entity is IMyCameraController) { MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 2."); } //MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1. {0}", VRage.Common.MySpectator.Static.IsInFirstPersonView); //System.Windows.Forms.Clipboard.SetText("hello"); if (spectator != null) { MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1."); MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. POS={0:N},{1:N},{2:N}", spectator.Position.X, spectator.Position.Y, spectator.Position.Z); } if (MyAPIGateway.Session.ControlledObject.Entity is MySpectator) { MyAPIGateway.Utilities.ShowMessage("Player", "Spectator2."); } //else //{ // MyAPIGateway.Utilities.ShowMessage("Player", "other."); //} MyAPIGateway.Utilities.ShowMessage("Controller", "ControlledEntity == ControlledObject : {0}", MyAPIGateway.Session.Player.Controller.ControlledEntity == MyAPIGateway.Session.ControlledObject); MyAPIGateway.Utilities.ShowMessage("Controller", "ControlledEntity == ControlledObject : {0}", MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity == MyAPIGateway.Session.ControlledObject.Entity); return(true); var playerMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; var playerPosition = playerMatrix.Translation + playerMatrix.Forward * 0.5f + playerMatrix.Up * 1.0f; MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", playerPosition.X, playerPosition.Y, playerPosition.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z)); //MyAPIGateway.Utilities.ShowMessage("Up", string.Format("x={0:N},y={1:N},z={2:N}", playerMatrix.Up.X, playerMatrix.Up.Y, playerMatrix.Up.Z)); // TODO: need to properly establish control state and how to tell which state we are in. // Player - First person. // Player - thrid person. // Cockpit - First person. ControlledObject.GetHeadMatrix(true, true, true); // Cockpit - thrid person. ControlledObject.GetHeadMatrix(true, true, true); // Spectator freeview. CameraController.GetViewMatrix() but corrupted pos and vector. // Camera. CameraController.GetViewMatrix() //MyAPIGateway.Session.Player.PlayerCharacter.GetHeadMatrix(true, true, true); //MyAPIGateway.Session.CameraController.GetViewMatrix(); //MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true); //Sandbox.ModAPI.IMyControllerInfo //? //Sandbox.ModAPI.IMyEntityController //Sandbox.ModAPI.Interfaces.IMyCameraController //Sandbox.ModAPI.Interfaces.IMyControllableEntity // The CameraController.GetViewMatrix appears warped at the moment. //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition(); //var camMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix(); //var camPosition = camMatrix.Translation; //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", camPosition.X, camPosition.Y, camPosition.Z, camMatrix.Forward.X, camMatrix.Forward.Y, camMatrix.Forward.Z)); //var worldMatrix = MyAPIGateway.Session.ControlledObject.Entity.WorldMatrix; var worldMatrix = MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true); var position = worldMatrix.Translation; MyAPIGateway.Utilities.ShowMessage("Con", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z)); //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(0, 0), 90f); //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(3.14f, 0), 0f); //MyAPIGateway.Session.Player.PlayerCharacter.Up(); // thrust, walk player forward? //MyAPIGateway.Session.Player.PlayerCharacter.Entity.worldmatrix //var character = (MyObjectBuilder_Character)obj; return(true); } #endregion #region test5 if (messageText.Equals("/test5", StringComparison.InvariantCultureIgnoreCase)) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f; var entites = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary <IMyEntity, double>(); foreach (var entity in entites) { var cubeGrid = entity as IMyCubeGrid; // check if the ray comes anywhere near the Grid before continuing. var ray = new RayD(position, worldMatrix.Forward); if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(position, worldMatrix.Forward * 1000); if (hit.HasValue) { var blocks = new List <IMySlimBlock>(); cubeGrid.GetBlocks(blocks, f => f.FatBlock != null); MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB)); // var block = blocks[0]; // //block.wo // var hsv = block.FatBlock.GetDiffuseColor(); // MyAPIGateway.Utilities.ShowMessage("Hsv", string.Format("{0},{1},{2} {3}", hsv.X, hsv.Y, hsv.Z, 1.45f)); // var c = VRageMath.ColorExtensions.HSVtoColor(hsv); // MyAPIGateway.Utilities.ShowMessage("Rgb", string.Format("{0},{1},{2}", c.R, c.G, c.B)); } } } return(true); } #endregion #region test6 if (messageText.Equals("/test6", StringComparison.InvariantCultureIgnoreCase)) { var entity = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity; //MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB)); //MyAPIGateway.Utilities.ShowMessage("Size", string.Format("{0}", entity.WorldAABB.Size())); //if (entity is IMyPlayer) // MyAPIGateway.Utilities.ShowMessage("IMyPlayer", "true"); //if (entity is IMyCubeBlock) // MyAPIGateway.Utilities.ShowMessage("IMyCubeBlock", "true"); // Ship //if (entity is IMyCubeGrid) // MyAPIGateway.Utilities.ShowMessage("IMyCubeGrid", "true"); //if (entity is IMyIdentity) // MyAPIGateway.Utilities.ShowMessage("IMyIdentity", "true"); //if (entity is IMyNetworkClient) // MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", "true"); //if (entity is IMyEntityController) // MyAPIGateway.Utilities.ShowMessage("IMyEntityController", "true"); //if (entity is IMyControllableEntity) // MyAPIGateway.Utilities.ShowMessage("IMyControllableEntity", "true"); // Ship and player //if (entity is IMyCameraController) // MyAPIGateway.Utilities.ShowMessage("IMyCameraController", "true"); // Everything //if (entity is IMyMultiplayer) // MyAPIGateway.Utilities.ShowMessage("IMyMultiplayer", "true"); if (entity is IMyCubeGrid) { entity = entity.Parent; } if (entity.Physics != null) { var pos = entity.GetPosition(); //var pos = Vector3.Zero; var m = Matrix.CreateWorld(pos, Vector3.Forward, Vector3.Up); entity.SetWorldMatrix(m); //MyAPIGateway.Multiplayer.SendEntitiesCreated(); //entity.LocalMatrix //entity.SetPosition(pos); //if (entity.SyncObject.UpdatesOnlyOnServer) // entity.SyncObject.UpdatePosition(); //MyAPIGateway.Utilities.ShowMessage("Physics=null", string.Format("{0}", phys == null)); MyAPIGateway.Utilities.ShowMessage("LinearVelocity", string.Format("{0}", entity.Physics.LinearVelocity)); //MyAPIGateway.Utilities.ShowMessage("Speed", string.Format("{0}", phys.Speed)); //MyAPIGateway.Utilities.ShowMessage("Mass", string.Format("{0}", phys.Mass)); //phys.AddForce(Sandbox.Engine.Physics.MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, Vector3.Forward, Vector3.Zero, Vector3.Zero); //phys.LinearVelocity = Vector3.Forward; //phys } //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. return(true); } #endregion #region test7 if (messageText.Equals("/test7", StringComparison.InvariantCultureIgnoreCase)) { var character = (MyObjectBuilder_Character)MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder(); //var obj = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder(); var obj = MyAPIGateway.Session.Player.Client as IMyEntity; MyAPIGateway.Utilities.ShowMessage("isNull", string.Format("{0}", obj == null)); //MyAPIGateway.Utilities.ShowMessage("Name", string.Format("{0}", obj.GetType().Name)); return(true); } #endregion #region test8 if (messageText.Equals("/test8A", StringComparison.InvariantCultureIgnoreCase)) { var gridBuilder = new MyObjectBuilder_CubeGrid() { PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, GridSizeEnum = MyCubeSize.Large, IsStatic = true, LinearVelocity = new SerializableVector3(0, 0, 0), AngularVelocity = new SerializableVector3(0, 0, 0), PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up), DisplayName = "test grid" }; MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock(); cube.Min = new SerializableVector3I(0, 0, 0); cube.SubtypeName = "LargeBlockArmorBlock"; cube.ColorMaskHSV = new SerializableVector3(0, -1, 0); cube.EntityId = 0; cube.Owner = 0; cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up); cube.ShareMode = MyOwnershipShareModeEnum.All; gridBuilder.CubeBlocks.Add(cube); // multiple grids... //var tempList = new List<MyObjectBuilder_EntityBase>(); //tempList.Add(gridBuilder); //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //tempList.ForEach(grid => MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(grid)); //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList); // Single grid. MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder); MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder); MyAPIGateway.Multiplayer.SendEntitiesCreated(new List <MyObjectBuilder_EntityBase> { gridBuilder }); MyAPIGateway.Utilities.ShowMessage("OK", "fine"); return(true); } if (messageText.Equals("/test8B", StringComparison.InvariantCultureIgnoreCase)) { var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, true, false, false, true, false) as IMyCubeGrid; if (entity == null) { return(false); } var gridBuilder = new MyObjectBuilder_CubeGrid() { PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, GridSizeEnum = MyCubeSize.Large, IsStatic = true, LinearVelocity = new SerializableVector3(0, 0, 0), AngularVelocity = new SerializableVector3(0, 0, 0), PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up), DisplayName = "test grid" }; MyObjectBuilder_CubeBlock cube = new MyObjectBuilder_CubeBlock(); cube.Min = new SerializableVector3I(0, 0, 0); cube.SubtypeName = "LargeBlockArmorBlock"; cube.ColorMaskHSV = new SerializableVector3(0, -1, 0); cube.ShareMode = MyOwnershipShareModeEnum.None; cube.Owner = 0; cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up); cube.ShareMode = MyOwnershipShareModeEnum.All; gridBuilder.CubeBlocks.Add(cube); //var tempList = new List<MyObjectBuilder_EntityBase>(); //tempList.Add(gridBuilder); //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //no need for this on new object //var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(tempList[0]); //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList); MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder); var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder); MyAPIGateway.Multiplayer.SendEntitiesCreated(new List <MyObjectBuilder_EntityBase> { gridBuilder }); entity.MergeGrid_MergeBlock(newEntity, new Vector3I(0, 1, 0)); MyAPIGateway.Utilities.ShowMessage("OK", "fine"); return(true); } #endregion #region test9 if (messageText.Equals("/test9", StringComparison.InvariantCultureIgnoreCase)) { var allEntites = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(allEntites, e => e != null); var sphere = new BoundingSphereD(Vector3D.Zero, 1000000f); var allSphereEntities = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere); MyAPIGateway.Utilities.ShowMessage("All Entities", String.Format("{0} == {1} ??", allEntites.Count, allSphereEntities.Count)); return(true); } #endregion #region test10 // attached grid count test. if (messageText.Equals("/test10", StringComparison.InvariantCultureIgnoreCase)) { var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, false, false, false, false, false) as IMyCubeGrid; if (entity == null) { return(false); } var cubeGrid = (IMyCubeGrid)entity; var grids = cubeGrid.GetAttachedGrids(); MyAPIGateway.Utilities.ShowMessage("Attached Count", "{0}", grids.Count); foreach (var grid in grids) { MyAPIGateway.Utilities.ShowMessage("Attached", "Id:{0}", grid.EntityId); } // Terminal Groups.... var gridTerminalSystem = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid); var groups = new List <IMyBlockGroup>(); gridTerminalSystem.GetBlockGroups(groups); // may abide by the owner rules? //MyAPIGateway.Utilities.ShowMessage("BlockGroup Count", "{0}", groups.Count); //foreach (var group in groups) // MyAPIGateway.Utilities.ShowMessage("BlockGroup", "name:{0} blocks:{1} Id:{2}", group.Name, group.Blocks.Count, group.Blocks.Count > 0 ? group.Blocks[0].CubeGrid.EntityId : 0); //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count)); return(true); } #endregion #region test11 if (messageText.Equals("/test11", StringComparison.InvariantCultureIgnoreCase)) { //var identities = new List<IMyIdentity>(); //MyAPIGateway.Players.GetAllIdentites(identities); //var ident = identities.FirstOrDefault(); //var bIdent = ((IMyEntity)ident).GetObjectBuilder(); //MyAPIGateway.Utilities.ShowMessage("IMyIdentity", string.Format("{0}", bIdent.GetType())); var players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p != null); var player = players.FirstOrDefault(); var cpnt = MyAPIGateway.Session.GetCheckpoint("null"); MyAPIGateway.Utilities.ShowMessage("cpnt", cpnt.Clients == null ? "null" : string.Format("{0}", cpnt.Clients.Count)); var c = MyAPIGateway.Session.GetWorld().Checkpoint.Clients; MyAPIGateway.Utilities.ShowMessage("Count", c == null ? "null" : string.Format("{0}", c.Count)); var nc = player.Client; MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType())); //MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType().BaseType)); //var bPlayer = ((IMyEntity)nc).GetObjectBuilder(); //MyAPIGateway.Utilities.ShowMessage("IMyPlayer", string.Format("{0}", bPlayer.GetType())); //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. return(true); } #endregion #region test12 if (messageText.Equals("/test12", StringComparison.InvariantCultureIgnoreCase)) { var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, true, true, true, true, true); var resultList = new List <ITerminalAction>(); if (entity != null) { var displayName = entity.DisplayName; MyAPIGateway.Utilities.ShowMessage("ID", displayName); MyAPIGateway.Utilities.ShowMessage("Components", string.Format("{0}", entity.Components == null)); MyAPIGateway.Utilities.ShowMessage("Hierarchy", string.Format("{0}", entity.Hierarchy == null)); var cockpits = entity.FindWorkingCockpits(); var terminal = (IMyTerminalBlock)cockpits[0]; //cockpits[0] terminal.GetActions(resultList); MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); } //Vector3D? FindFreePlace(Vector3D basePos, float radius, int maxTestCount = 20, int testsPerDistance = 5, float stepSize = 1f); //MyAPIGateway.Entities.FindFreePlace( //resultList.Clear(); //var myObject = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(typeof(MyObjectBuilder_Reactor), "SmallBlockLargeGenerator"); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(MyObjectBuilder_Reactor), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyMotorStator), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyFunctionalBlock), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyTerminalBlock), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); foreach (var a in resultList) { MyAPIGateway.Utilities.ShowMessage("item", string.Format("{0}={1}", a.Name, a.Id)); } return(true); } #endregion #region test13 if (messageText.Equals("/test13", StringComparison.InvariantCultureIgnoreCase)) { var entites = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); //var physicalItem = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(typeof(MyObjectBuilder_SpaceBall), "SpaceBallLarge")); //physicalItem.Public = true; //MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed = 2000; //MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed = 2000; MyAPIGateway.Session.GetCheckpoint("null").GameMode = MyGameModeEnum.Creative; //MyAPIGateway.Session.GetCheckpoint("null").CargoShipsEnabled //MyAPIGateway.Session.GetCheckpoint("null").EnableCopyPaste = true; //MyAPIGateway.Utilities.ShowMessage("Sun Distance", string.Format("{0}", MyDefinitionManager.Static.EnvironmentDefinition.DistanceToSun)); //MyDefinitionManager.Static.EnvironmentDefinition.DirectionToSun = new Vector3(0, 1, 0); foreach (var entity in entites) { var cubeGrid = entity as IMyCubeGrid; if (cubeGrid != null) { var terminalsys = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid); //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count)); //var blocks = new List<Sandbox.ModAPI.IMySlimBlock>(); //cubeGrid.GetBlocks(blocks, f => f.FatBlock != null && f.FatBlock == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity); //MyAPIGateway.Utilities.ShowMessage("Pilot count", string.Format("{0}", blocks.Count)); //cubeGrid.GetBlocks(blocks); //foreach (var block in blocks) //{ // cubeGrid.ColorBlocks(block.Position, block.Position, VRageMath.Color.Gold.ToHsvColor()); //} } } return(true); } #endregion #region test14 if (messageText.Equals("/test14", StringComparison.InvariantCultureIgnoreCase)) { // Tag every floating object in player GPS. //var entites = new HashSet<IMyEntity>(); //MyAPIGateway.Entities.GetEntities(entites, e => (e is Sandbox.ModAPI.IMyFloatingObject)); //foreach (var entity in entites) //{ // var pos = entity.GetPosition(); // var gps = MyAPIGateway.Session.GPS.Create("Floating " + entity.DisplayName, "Some drifting junk", pos, true, false); // MyAPIGateway.Session.GPS.AddLocalGps(gps); //} //// Tag the Head position, and current position of the player. //var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, false, false); // dead center of player cross hairs. //var gps = MyAPIGateway.Session.GPS.Create("GetHeadMatrix", "", worldMatrix.Translation, true, false); ////MyAPIGateway.Session.GPS.AddLocalGps(gps); //gps = MyAPIGateway.Session.GPS.Create("GetPosition", "", MyAPIGateway.Session.Player.GetPosition(), true, false); ////MyAPIGateway.Session.GPS.AddLocalGps(gps); //var pos1 = worldMatrix.Translation; //var pos2 = MyAPIGateway.Session.Player.GetPosition(); //var pos = pos2 - pos1; //MyAPIGateway.Utilities.ShowMessage("Distance", "{0}", pos.Length()); var clients = MyAPIGateway.Session.GetCheckpoint("null").Clients; if (clients != null) { IMyPlayer player = MyAPIGateway.Session.Player; MyObjectBuilder_Client client = clients.FirstOrDefault(c => c.SteamId == player.SteamUserId && c.IsAdmin); if (client == null) { client = new MyObjectBuilder_Client() { IsAdmin = true, SteamId = player.SteamUserId, Name = player.DisplayName }; clients.Add(client); MyAPIGateway.Utilities.ShowMessage("Check", "added admin"); } else { MyAPIGateway.Utilities.ShowMessage("Check", "already admin"); } } return(true); } #endregion return(false); }
internal void InitialHitCheck() { var vhCount = ValidateHits.Count; var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999; var stride = vhCount < minCount ? 100000 : 48; MyAPIGateway.Parallel.For(0, ValidateHits.Count, x => { var p = ValidateHits[x]; var shieldByPass = p.Info.ConsumableDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Bypass; var shieldFullBypass = shieldByPass && p.Info.ConsumableDef.Const.ShieldBypassMod >= 1; var genericFields = p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == PushField || p.Info.ConsumableDef.Const.AreaEffect == PullField); p.FinalizeIntersection = false; var lineCheck = p.Info.ConsumableDef.Const.CollisionIsLine && !p.Info.EwarAreaPulse; var ewarProjectile = (p.Info.EwarActive || p.Info.ConsumableDef.Const.EwarEffect); bool projetileInShield = false; var tick = p.Info.System.Session.Tick; var useEntityCollection = p.CheckType != Projectile.CheckTypes.Ray; var entityCollection = p.UseEntityCache ? p.Info.Ai.NearByEntityCache : p.MyEntityList; var collectionCount = !useEntityCollection ? p.MySegmentList.Count : entityCollection.Count; var ray = new RayD(ref p.Beam.From, ref p.Beam.Direction); var myGrid = p.Info.Target.FiringCube.CubeGrid; Water water = null; if (Session.WaterApiLoaded && p.Info.MyPlanet != null) { Session.WaterMap.TryGetValue(p.Info.MyPlanet, out water); } for (int i = 0; i < collectionCount; i++) { var ent = !useEntityCollection ? p.MySegmentList[i].Element : entityCollection[i]; var grid = ent as MyCubeGrid; var entIsSelf = grid != null && (grid == myGrid || myGrid.IsSameConstructAs(grid)); if (entIsSelf && p.SmartsOn || ent.MarkedForClose || !ent.InScene || ent == p.Info.MyShield) { continue; } var character = ent as IMyCharacter; if (p.Info.EwarActive && character != null && !genericFields) { continue; } var entSphere = ent.PositionComp.WorldVolume; if (useEntityCollection) { if (p.CheckType == Projectile.CheckTypes.CachedRay) { var dist = ray.Intersects(entSphere); if (!dist.HasValue || dist > p.Beam.Length) { continue; } } else if (p.CheckType == Projectile.CheckTypes.CachedSphere && p.PruneSphere.Contains(entSphere) == ContainmentType.Disjoint) { continue; } } if (grid != null || character != null) { var extBeam = new LineD(p.Beam.From - p.Beam.Direction * (entSphere.Radius * 2), p.Beam.To); var transform = ent.PositionComp.WorldMatrixRef; var box = ent.PositionComp.LocalAABB; var obb = new MyOrientedBoundingBoxD(box, transform); if (lineCheck && obb.Intersects(ref extBeam) == null || !lineCheck && !obb.Intersects(ref p.PruneSphere)) { continue; } } var safeZone = ent as MySafeZone; if (safeZone != null && safeZone.Enabled) { var action = (Session.SafeZoneAction)safeZone.AllowedActions; if ((action & Session.SafeZoneAction.Damage) == 0) { bool intersects; if (safeZone.Shape == MySafeZoneShape.Sphere) { var sphere = new BoundingSphereD(safeZone.PositionComp.WorldVolume.Center, safeZone.Radius); var dist = ray.Intersects(sphere); intersects = dist != null && dist <= p.Beam.Length; } else { intersects = new MyOrientedBoundingBoxD(safeZone.PositionComp.LocalAABB, safeZone.PositionComp.WorldMatrixRef).Intersects(ref p.Beam) != null; } if (intersects) { p.State = Projectile.ProjectileState.Depleted; p.EarlyEnd = true; if (p.EnableAv) { p.Info.AvShot.ForceHitParticle = true; } break; } } } HitEntity hitEntity = null; var checkShield = Session.ShieldApiLoaded && Session.ShieldHash == ent.DefinitionId?.SubtypeId && ent.Render.Visible; MyTuple <IMyTerminalBlock, MyTuple <bool, bool, float, float, float, int>, MyTuple <MatrixD, MatrixD> >?shieldInfo = null; if (checkShield && (!shieldFullBypass && !p.ShieldBypassed || p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == EmpField))) { shieldInfo = p.Info.System.Session.SApi.MatchEntToShieldFastExt(ent, true); if (shieldInfo != null && !myGrid.IsSameConstructAs(shieldInfo.Value.Item1.CubeGrid)) { if (p.Info.IsShrapnel || Vector3D.Transform(p.Info.Origin, shieldInfo.Value.Item3.Item1).LengthSquared() > 1) { p.EntitiesNear = true; var dist = MathFuncs.IntersectEllipsoid(shieldInfo.Value.Item3.Item1, shieldInfo.Value.Item3.Item2, new RayD(p.Beam.From, p.Beam.Direction)); if (p.Info.Target.IsProjectile && Vector3D.Transform(p.Info.Target.Projectile.Position, shieldInfo.Value.Item3.Item1).LengthSquared() <= 1) { projetileInShield = true; } if (dist != null && (dist.Value < p.Beam.Length || p.Info.EwarActive)) { if (shieldByPass) { p.ShieldBypassed = true; } hitEntity = HitEntityPool.Get(); hitEntity.EventType = Shield; hitEntity.HitPos = p.Beam.From + (p.Beam.Direction * dist.Value); hitEntity.HitDist = dist; } else { continue; } } } } var destroyable = ent as IMyDestroyableObject; var voxel = ent as MyVoxelBase; if (voxel != null && voxel == voxel?.RootVoxel) { if (ent == p.Info.MyPlanet && !(p.LinePlanetCheck || p.DynamicGuidance || p.CachedPlanetHit)) { continue; } VoxelIntersectBranch voxelState = VoxelIntersectBranch.None; Vector3D?voxelHit = null; if (tick - p.Info.VoxelCache.HitRefreshed < 60) { var cacheDist = ray.Intersects(p.Info.VoxelCache.HitSphere); if (cacheDist.HasValue && cacheDist.Value <= p.Beam.Length) { voxelHit = p.Beam.From + (p.Beam.Direction * cacheDist.Value); voxelState = VoxelIntersectBranch.PseudoHit1; } else if (cacheDist.HasValue) { p.Info.VoxelCache.MissSphere.Center = p.Beam.To; } } if (voxelState != VoxelIntersectBranch.PseudoHit1) { if (voxel == p.Info.MyPlanet && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint) { if (p.LinePlanetCheck) { if (water != null && !p.Info.ConsumableDef.IgnoreWater) { var waterSphere = new BoundingSphereD(p.Info.MyPlanet.PositionComp.WorldAABB.Center, water.radius); var estiamtedSurfaceDistance = ray.Intersects(waterSphere); if (estiamtedSurfaceDistance.HasValue && estiamtedSurfaceDistance.Value <= p.Beam.Length) { var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value); voxelHit = estimatedHit; voxelState = VoxelIntersectBranch.PseudoHit2; } } if (voxelState != VoxelIntersectBranch.PseudoHit2) { var surfacePos = p.Info.MyPlanet.GetClosestSurfacePointGlobal(ref p.Position); var planetCenter = p.Info.MyPlanet.PositionComp.WorldAABB.Center; double surfaceToCenter; Vector3D.DistanceSquared(ref surfacePos, ref planetCenter, out surfaceToCenter); double endPointToCenter; Vector3D.DistanceSquared(ref p.Position, ref planetCenter, out endPointToCenter); double startPointToCenter; Vector3D.DistanceSquared(ref p.Info.Origin, ref planetCenter, out startPointToCenter); var prevEndPointToCenter = p.PrevEndPointToCenterSqr; Vector3D.DistanceSquared(ref surfacePos, ref p.Position, out p.PrevEndPointToCenterSqr); if (surfaceToCenter > endPointToCenter || p.PrevEndPointToCenterSqr <= (p.Beam.Length * p.Beam.Length) || endPointToCenter > startPointToCenter && prevEndPointToCenter > p.DistanceToTravelSqr || surfaceToCenter > Vector3D.DistanceSquared(planetCenter, p.LastPosition)) { var estiamtedSurfaceDistance = ray.Intersects(p.Info.VoxelCache.PlanetSphere); var fullCheck = p.Info.VoxelCache.PlanetSphere.Contains(p.Info.Origin) != ContainmentType.Disjoint || !estiamtedSurfaceDistance.HasValue; if (!fullCheck && estiamtedSurfaceDistance.HasValue && (estiamtedSurfaceDistance.Value <= p.Beam.Length || p.Info.VoxelCache.PlanetSphere.Radius < 1)) { double distSqr; var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value); Vector3D.DistanceSquared(ref p.Info.VoxelCache.FirstPlanetHit, ref estimatedHit, out distSqr); if (distSqr > 625) { fullCheck = true; } else { voxelHit = estimatedHit; voxelState = VoxelIntersectBranch.PseudoHit2; } } if (fullCheck) { voxelState = VoxelIntersectBranch.DeferFullCheck; } if (voxelHit.HasValue && Vector3D.DistanceSquared(voxelHit.Value, p.Info.VoxelCache.PlanetSphere.Center) > p.Info.VoxelCache.PlanetSphere.Radius * p.Info.VoxelCache.PlanetSphere.Radius) { p.Info.VoxelCache.GrowPlanetCache(voxelHit.Value); } } } } } else if (voxelHit == null && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint) { voxelState = VoxelIntersectBranch.DeferedMissUpdate; } } if (voxelState == VoxelIntersectBranch.PseudoHit1 || voxelState == VoxelIntersectBranch.PseudoHit2) { if (!voxelHit.HasValue) { if (p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint) { p.Info.VoxelCache.MissSphere.Center = p.Beam.To; } continue; } hitEntity = HitEntityPool.Get(); var hitPos = voxelHit.Value; hitEntity.HitPos = hitPos; double dist; Vector3D.Distance(ref p.Beam.From, ref hitPos, out dist); hitEntity.HitDist = dist; hitEntity.EventType = Voxel; } else if (voxelState == VoxelIntersectBranch.DeferedMissUpdate || voxelState == VoxelIntersectBranch.DeferFullCheck) { DeferedVoxels.Add(new DeferedVoxels { Projectile = p, Branch = voxelState, Voxel = voxel }); } } else if (ent.Physics != null && !ent.Physics.IsPhantom && !ent.IsPreview && grid != null) { if (grid != null) { hitEntity = HitEntityPool.Get(); if (entIsSelf) { if (!p.Info.ConsumableDef.Const.IsBeamWeapon && p.Beam.Length <= grid.GridSize * 2) { MyCube cube; if (!(grid.TryGetCube(grid.WorldToGridInteger(p.Position), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock || grid.TryGetCube(grid.WorldToGridInteger(p.LastPosition), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock)) { HitEntityPool.Return(hitEntity); continue; } } if (!p.Info.EwarAreaPulse) { var forwardPos = p.Info.Age != 1 ? p.Beam.From : p.Beam.From + (p.Beam.Direction * Math.Min(grid.GridSizeHalf, p.Info.DistanceTraveled - p.Info.PrevDistanceTraveled)); grid.RayCastCells(forwardPos, p.Beam.To, hitEntity.Vector3ICache, null, true, true); if (hitEntity.Vector3ICache.Count > 0) { IHitInfo hitInfo; p.Info.System.Session.Physics.CastRay(forwardPos, p.Beam.To, out hitInfo, CollisionLayers.DefaultCollisionLayer); var hitGrid = hitInfo?.HitEntity?.GetTopMostParent() as MyCubeGrid; if (hitGrid == null || !myGrid.IsSameConstructAs(hitGrid)) { HitEntityPool.Return(hitEntity); continue; } hitEntity.HitPos = hitInfo.Position; hitEntity.Blocks.Add(grid.GetCubeBlock(hitEntity.Vector3ICache[0])); } } } else { grid.RayCastCells(p.Beam.From, p.Beam.To, hitEntity.Vector3ICache, null, true, true); } if (!ewarProjectile) { hitEntity.EventType = Grid; } else if (!p.Info.EwarAreaPulse) { hitEntity.EventType = Effect; } else { hitEntity.EventType = Field; } p.EntitiesNear = true; } } else if (destroyable != null) { hitEntity = HitEntityPool.Get(); hitEntity.EventType = Destroyable; } if (hitEntity != null) { p.FinalizeIntersection = true; hitEntity.Info = p.Info; hitEntity.Entity = hitEntity.EventType != Shield ? ent : (MyEntity)shieldInfo.Value.Item1; hitEntity.Intersection = p.Beam; hitEntity.SphereCheck = !lineCheck; hitEntity.PruneSphere = p.PruneSphere; hitEntity.SelfHit = entIsSelf; hitEntity.DamageOverTime = p.Info.ConsumableDef.Const.AreaEffect == DotField; p.Info.HitList.Add(hitEntity); } } if (p.Info.Target.IsProjectile && !p.Info.ConsumableDef.Const.EwarEffect && !projetileInShield) { var detonate = p.State == Projectile.ProjectileState.Detonate; var hitTolerance = detonate ? p.Info.ConsumableDef.Const.DetonationRadius : p.Info.ConsumableDef.Const.AreaEffectSize > p.Info.ConsumableDef.Const.CollisionSize ? p.Info.ConsumableDef.Const.AreaEffectSize : p.Info.ConsumableDef.Const.CollisionSize; var useLine = p.Info.ConsumableDef.Const.CollisionIsLine && !detonate && p.Info.ConsumableDef.Const.AreaEffectSize <= 0; var sphere = new BoundingSphereD(p.Info.Target.Projectile.Position, p.Info.Target.Projectile.Info.ConsumableDef.Const.CollisionSize); sphere.Include(new BoundingSphereD(p.Info.Target.Projectile.LastPosition, 1)); bool rayCheck = false; if (useLine) { var dist = sphere.Intersects(new RayD(p.LastPosition, p.Info.Direction)); if (dist <= hitTolerance || p.Info.ConsumableDef.Const.IsBeamWeapon && dist <= p.Beam.Length) { rayCheck = true; } } var testSphere = p.PruneSphere; testSphere.Radius = hitTolerance; if (rayCheck || sphere.Intersects(testSphere)) { ProjectileHit(p, p.Info.Target.Projectile, lineCheck, ref p.Beam); } } if (!useEntityCollection) { p.MySegmentList.Clear(); } else if (p.CheckType == Projectile.CheckTypes.Sphere) { entityCollection.Clear(); } if (p.FinalizeIntersection) { FinalHitCheck.Add(p); } }, stride); ValidateHits.ClearImmediate(); }
public override bool Invoke(string messageText) { #region test if (messageText.Equals("/test", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. //MyAPIGateway.Utilities.ShowMessage("path", MyAPIGateway.Session.CurrentPath); //MyAPIGateway.Utilities.ShowMessage("size1", MyAPIGateway.Utilities.ConfigDedicated.SessionSettings.WorldSizeKm.ToString()); //MyAPIGateway.Utilities.ShowMessage("size2", MyAPIGateway.Session.GetWorld().Checkpoint.Settings.WorldSizeKm.ToString()); IMyConfigDedicated config = null; //List<string> admins = null; try { config = MyAPIGateway.Utilities.ConfigDedicated; config.Load(); //config. } catch (Exception) { MyAPIGateway.Utilities.ShowMessage("Exception", "ConfigDedicated"); //ex.Message); } if (config != null) { try { var players = new List<IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p != null); MyAPIGateway.Utilities.ShowMessage("Player Count", string.Format("{0}", players.Count)); var identities = new List<IMyIdentity>(); MyAPIGateway.Players.GetAllIdentites(identities); MyAPIGateway.Utilities.ShowMessage("Identities Count", string.Format("{0}", identities.Count)); MyAPIGateway.Utilities.ShowMessage("Admin Count", string.Format("{0}", config.Administrators.Count)); //MyAPIGateway.Utilities.ShowMessage("WorldName", string.Format("{0}", config.WorldName)); //MyAPIGateway.Utilities.ShowMessage("WorldSize", string.Format("{0}", config.SessionSettings.WorldSizeKm)); MyAPIGateway.Utilities.ShowMessage("Mods Count", string.Format("{0}", config.Mods.Count)); //MyAPIGateway.Utilities.ShowMessage("IP", string.Format("{0}", config.IP)); var clients = MyAPIGateway.Session.GetWorld().Checkpoint.Clients; MyAPIGateway.Utilities.ShowMessage("Client Count", clients == null ? "null" : string.Format("{0}", clients.Count)); if (clients != null) { var client = clients.FirstOrDefault(c => c.SteamId == MyAPIGateway.Multiplayer.MyId); if (client != null) { MyAPIGateway.Utilities.ShowMessage("IsAdmin", string.Format("{0}", client.IsAdmin)); } } } catch (Exception) { MyAPIGateway.Utilities.ShowMessage("Exception", "reading config"); //ex.Message); } } return true; } #endregion #region test2 if (messageText.Equals("/test2", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. var count = MyAPIGateway.Utilities.ConfigDedicated.Administrators.Count.ToString(CultureInfo.InvariantCulture); MyAPIGateway.Utilities.ShowMessage("Admins", string.Format("Count {0}", count)); MyAPIGateway.Utilities.ShowMessage("Players", string.Format("Count {0}", MyAPIGateway.Players.Count)); MyAPIGateway.Utilities.ShowMessage("MultiPlayers", string.Format("Count {0}", MyAPIGateway.Multiplayer.Players.Count)); return true; } #endregion #region test3 if (messageText.Equals("/test3", StringComparison.InvariantCultureIgnoreCase)) { // for testing things. MyAPIGateway.Utilities.ShowMessage("MyId", "{0}", MyAPIGateway.Multiplayer.MyId); MyAPIGateway.Utilities.ShowMessage("SteamId", "{0}", MyAPIGateway.Session.Player.SteamUserId); MyAPIGateway.Utilities.ShowMessage("MyName", "{0}", MyAPIGateway.Multiplayer.MyName); MyAPIGateway.Utilities.ShowMessage("IsServer", "{0}", MyAPIGateway.Multiplayer.IsServer); MyAPIGateway.Utilities.ShowMessage("IsServerPlayer", "{0}", MyAPIGateway.Multiplayer.IsServerPlayer(MyAPIGateway.Session.Player.Client)); MyAPIGateway.Utilities.ShowMessage("MultiplayerActive", "{0}", MyAPIGateway.Multiplayer.MultiplayerActive); MyAPIGateway.Utilities.ShowMessage("OnlineMode", "{0}", MyAPIGateway.Session.OnlineMode); MyAPIGateway.Utilities.ShowMessage("IsDedicated", "{0}", MyAPIGateway.Utilities.IsDedicated); //MyAPIGateway.Utilities.ShowMessage("Culture", "{0}", MyTexts.Culture.IetfLanguageTag); MyAPIGateway.Utilities.ShowMessage("Culture", "{0} {1}", CultureInfo.CurrentUICulture, CultureInfo.CurrentUICulture.IetfLanguageTag); var ed = ((MyObjectBuilder_EnvironmentDefinition)MyDefinitionManager.Static.EnvironmentDefinition.GetObjectBuilder()); MyAPIGateway.Utilities.ShowMessage("LargeShipMaxSpeed", "{0}", ed.LargeShipMaxSpeed); MyAPIGateway.Utilities.ShowMessage("SunDirection", "{0} {1} {2}", ed.SunDirection.X, ed.SunDirection.Y, ed.SunDirection.Z); return true; } #endregion #region test4 if (messageText.Equals("/test4", StringComparison.InvariantCultureIgnoreCase)) { var player = MyAPIGateway.Session.Player; if (player != null) { var pos = player.GetPosition(); MyAPIGateway.Utilities.ShowMessage("Player", "pos={0:N},{1:N},{2:N}", pos.X, pos.Y, pos.Z); } var cockpit = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyCockpit; var remoteControl = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyRemoteControl; var character = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.IMyCharacter; var character2 = MyAPIGateway.Session.ControlledObject as Sandbox.Game.Entities.Character.MyCharacter; var camera = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.IMyCamera; var cameraBlock = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Ingame.IMyCameraBlock; var cameraController = MyAPIGateway.Session.ControlledObject as Sandbox.ModAPI.Interfaces.IMyCameraController; var spectator = MyAPIGateway.Session.ControlledObject as VRage.MySpectator; if (cockpit != null) { MyAPIGateway.Utilities.ShowMessage("Control", "in cockpit."); } if (remoteControl != null) { MyAPIGateway.Utilities.ShowMessage("Control", "remoting."); } if (character != null) { MyAPIGateway.Utilities.ShowMessage("Control", "character."); } if (character2 != null) { //var pos = character2.PositionComp.GetPosition(); // Uses MyEntity which is not whitelisted. MyAPIGateway.Utilities.ShowMessage("Control", "character2."); } if (camera != null) { MyAPIGateway.Utilities.ShowMessage("Control", "camera."); } if (cameraBlock != null) { MyAPIGateway.Utilities.ShowMessage("Control", "camera block."); } if (cameraController != null) { var pos = cameraController.GetViewMatrix().Translation; MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 1. FPV={0} POS={1:N},{2:N},{3:N}", cameraController.IsInFirstPersonView, pos.X, pos.Y, pos.Z); } if (MyAPIGateway.Session.ControlledObject.Entity is Sandbox.ModAPI.Interfaces.IMyCameraController) { MyAPIGateway.Utilities.ShowMessage("Control", "camera controller 2."); } //MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1. {0}", VRage.Common.MySpectator.Static.IsInFirstPersonView); //System.Windows.Forms.Clipboard.SetText("hello"); if (spectator != null) { MyAPIGateway.Utilities.ShowMessage("Player", "Spectator1."); } if (MyAPIGateway.Session.ControlledObject.Entity is MySpectator) { MyAPIGateway.Utilities.ShowMessage("Player", "Spectator2."); } //else //{ // MyAPIGateway.Utilities.ShowMessage("Player", "other."); //} return true; var playerMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; var playerPosition = playerMatrix.Translation + playerMatrix.Forward * 0.5f + playerMatrix.Up * 1.0f; MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", playerPosition.X, playerPosition.Y, playerPosition.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z)); //MyAPIGateway.Utilities.ShowMessage("Up", string.Format("x={0:N},y={1:N},z={2:N}", playerMatrix.Up.X, playerMatrix.Up.Y, playerMatrix.Up.Z)); // TODO: need to properly establish control state and how to tell which state we are in. // Player - First person. // Player - thrid person. // Cockpit - First person. ControlledObject.GetHeadMatrix(true, true, true); // Cockpit - thrid person. ControlledObject.GetHeadMatrix(true, true, true); // Spectator freeview. CameraController.GetViewMatrix() but corrupted pos and vector. // Camera. CameraController.GetViewMatrix() //MyAPIGateway.Session.Player.PlayerCharacter.GetHeadMatrix(true, true, true); //MyAPIGateway.Session.CameraController.GetViewMatrix(); //MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true); //Sandbox.ModAPI.IMyControllerInfo //? //Sandbox.ModAPI.IMyEntityController //Sandbox.ModAPI.Interfaces.IMyCameraController //Sandbox.ModAPI.Interfaces.IMyControllableEntity // The CameraController.GetViewMatrix appears warped at the moment. //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition(); var camMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix(); var camPosition = camMatrix.Translation; MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", camPosition.X, camPosition.Y, camPosition.Z, camMatrix.Forward.X, camMatrix.Forward.Y, camMatrix.Forward.Z)); //var worldMatrix = MyAPIGateway.Session.ControlledObject.Entity.WorldMatrix; var worldMatrix = MyAPIGateway.Session.ControlledObject.GetHeadMatrix(true, true, true); var position = worldMatrix.Translation; MyAPIGateway.Utilities.ShowMessage("Con", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z)); //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(0, 0), 90f); //MyAPIGateway.Session.Player.PlayerCharacter.MoveAndRotate(new Vector3(), new Vector2(3.14f, 0), 0f); //MyAPIGateway.Session.Player.PlayerCharacter.Up(); // thrust, walk player forward? //MyAPIGateway.Session.Player.PlayerCharacter.Entity.worldmatrix //var character = (MyObjectBuilder_Character)obj; return true; } #endregion #region test5 if (messageText.Equals("/test5", StringComparison.InvariantCultureIgnoreCase)) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f; var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary<IMyEntity, double>(); foreach (var entity in entites) { var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid; // check if the ray comes anywhere near the Grid before continuing. var ray = new RayD(position, worldMatrix.Forward); if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(position, worldMatrix.Forward * 1000); if (hit.HasValue) { var blocks = new List<Sandbox.ModAPI.IMySlimBlock>(); cubeGrid.GetBlocks(blocks, f => f.FatBlock != null); MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB)); // var block = blocks[0]; // //block.wo // var hsv = block.FatBlock.GetDiffuseColor(); // MyAPIGateway.Utilities.ShowMessage("Hsv", string.Format("{0},{1},{2} {3}", hsv.X, hsv.Y, hsv.Z, 1.45f)); // var c = VRageMath.ColorExtensions.HSVtoColor(hsv); // MyAPIGateway.Utilities.ShowMessage("Rgb", string.Format("{0},{1},{2}", c.R, c.G, c.B)); } } } return true; } #endregion #region test6 if (messageText.Equals("/test6", StringComparison.InvariantCultureIgnoreCase)) { var entity = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity; //MyAPIGateway.Utilities.ShowMessage("AABB", string.Format("{0}", entity.WorldAABB)); //MyAPIGateway.Utilities.ShowMessage("Size", string.Format("{0}", entity.WorldAABB.Size())); //if (entity is IMyPlayer) // MyAPIGateway.Utilities.ShowMessage("IMyPlayer", "true"); //if (entity is IMyCubeBlock) // MyAPIGateway.Utilities.ShowMessage("IMyCubeBlock", "true"); // Ship //if (entity is IMyCubeGrid) // MyAPIGateway.Utilities.ShowMessage("IMyCubeGrid", "true"); //if (entity is IMyIdentity) // MyAPIGateway.Utilities.ShowMessage("IMyIdentity", "true"); //if (entity is IMyNetworkClient) // MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", "true"); //if (entity is IMyEntityController) // MyAPIGateway.Utilities.ShowMessage("IMyEntityController", "true"); //if (entity is IMyControllableEntity) // MyAPIGateway.Utilities.ShowMessage("IMyControllableEntity", "true"); // Ship and player //if (entity is IMyCameraController) // MyAPIGateway.Utilities.ShowMessage("IMyCameraController", "true"); // Everything //if (entity is IMyMultiplayer) // MyAPIGateway.Utilities.ShowMessage("IMyMultiplayer", "true"); if (entity is Sandbox.ModAPI.IMyCubeGrid) entity = entity.Parent; if (entity.Physics != null) { var pos = entity.GetPosition(); //var pos = Vector3.Zero; var m = Matrix.CreateWorld(pos, Vector3.Forward, Vector3.Up); entity.SetWorldMatrix(m); //MyAPIGateway.Multiplayer.SendEntitiesCreated(); //entity.LocalMatrix //entity.SetPosition(pos); //if (entity.SyncObject.UpdatesOnlyOnServer) // entity.SyncObject.UpdatePosition(); //MyAPIGateway.Utilities.ShowMessage("Physics=null", string.Format("{0}", phys == null)); MyAPIGateway.Utilities.ShowMessage("LinearVelocity", string.Format("{0}", entity.Physics.LinearVelocity)); //MyAPIGateway.Utilities.ShowMessage("Speed", string.Format("{0}", phys.Speed)); //MyAPIGateway.Utilities.ShowMessage("Mass", string.Format("{0}", phys.Mass)); //phys.AddForce(Sandbox.Engine.Physics.MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, Vector3.Forward, Vector3.Zero, Vector3.Zero); //phys.LinearVelocity = Vector3.Forward; //phys } //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. return true; } #endregion #region test7 if (messageText.Equals("/test7", StringComparison.InvariantCultureIgnoreCase)) { var character = (MyObjectBuilder_Character)MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder(); //var obj = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.GetObjectBuilder(); var obj = MyAPIGateway.Session.Player.Client as IMyEntity; MyAPIGateway.Utilities.ShowMessage("isNull", string.Format("{0}", obj == null)); //MyAPIGateway.Utilities.ShowMessage("Name", string.Format("{0}", obj.GetType().Name)); return true; } #endregion #region test8 if (messageText.Equals("/test8A", StringComparison.InvariantCultureIgnoreCase)) { var gridBuilder = new MyObjectBuilder_CubeGrid() { PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, GridSizeEnum = MyCubeSize.Large, IsStatic = true, LinearVelocity = new SerializableVector3(0, 0, 0), AngularVelocity = new SerializableVector3(0, 0, 0), PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up), DisplayName = "test grid" }; Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock cube = new Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock(); cube.Min = new SerializableVector3I(0, 0, 0); cube.SubtypeName = "LargeBlockArmorBlock"; cube.ColorMaskHSV = new SerializableVector3(0, -1, 0); cube.ShareMode = MyOwnershipShareModeEnum.None; cube.EntityId = 0; cube.Owner = 0; cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up); cube.ShareMode = Sandbox.Common.ObjectBuilders.MyOwnershipShareModeEnum.All; gridBuilder.CubeBlocks.Add(cube); // multiple grids... //var tempList = new List<MyObjectBuilder_EntityBase>(); //tempList.Add(gridBuilder); //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //tempList.ForEach(grid => MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(grid)); //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList); // Single grid. MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder); MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder); MyAPIGateway.Multiplayer.SendEntitiesCreated(new List<MyObjectBuilder_EntityBase> { gridBuilder }); MyAPIGateway.Utilities.ShowMessage("OK", "fine"); return true; } if (messageText.Equals("/test8B", StringComparison.InvariantCultureIgnoreCase)) { var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject, true, false, false) as Sandbox.ModAPI.IMyCubeGrid; if (entity == null) return false; var gridBuilder = new MyObjectBuilder_CubeGrid() { PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, GridSizeEnum = MyCubeSize.Large, IsStatic = true, LinearVelocity = new SerializableVector3(0, 0, 0), AngularVelocity = new SerializableVector3(0, 0, 0), PositionAndOrientation = new MyPositionAndOrientation(Vector3.Zero, Vector3.Forward, Vector3.Up), DisplayName = "test grid" }; Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock cube = new Sandbox.Common.ObjectBuilders.MyObjectBuilder_CubeBlock(); cube.Min = new SerializableVector3I(0, 0, 0); cube.SubtypeName = "LargeBlockArmorBlock"; cube.ColorMaskHSV = new SerializableVector3(0, -1, 0); cube.ShareMode = MyOwnershipShareModeEnum.None; cube.Owner = 0; cube.BlockOrientation = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up); cube.ShareMode = Sandbox.Common.ObjectBuilders.MyOwnershipShareModeEnum.All; gridBuilder.CubeBlocks.Add(cube); //var tempList = new List<MyObjectBuilder_EntityBase>(); //tempList.Add(gridBuilder); //MyAPIGateway.Entities.RemapObjectBuilderCollection(tempList); //no need for this on new object //var newEntity = (IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(tempList[0]); //MyAPIGateway.Multiplayer.SendEntitiesCreated(tempList); MyAPIGateway.Entities.RemapObjectBuilder(gridBuilder); var newEntity = (Sandbox.ModAPI.IMyCubeGrid)MyAPIGateway.Entities.CreateFromObjectBuilderAndAdd(gridBuilder); MyAPIGateway.Multiplayer.SendEntitiesCreated(new List<MyObjectBuilder_EntityBase> { gridBuilder }); entity.MergeGrid_MergeBlock(newEntity, new Vector3I(0, 1, 0)); MyAPIGateway.Utilities.ShowMessage("OK", "fine"); return true; } #endregion #region test9 if (messageText.Equals("/test9", StringComparison.InvariantCultureIgnoreCase)) { var allEntites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(allEntites, e => e != null); var sphere = new BoundingSphereD(Vector3D.Zero, 1000000f); var allSphereEntities = MyAPIGateway.Entities.GetEntitiesInSphere(ref sphere); MyAPIGateway.Utilities.ShowMessage("All Entities", String.Format("{0} == {1} ??", allEntites.Count, allSphereEntities.Count)); return true; } #endregion #region test10 if (messageText.StartsWith("/test10 ", StringComparison.InvariantCultureIgnoreCase)) { var match = Regex.Match(messageText, @"/test10\s{1,}(?<Key>.+)", RegexOptions.IgnoreCase); if (match.Success) { var prefabName = match.Groups["Key"].Value; var entities = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities, e => e is Sandbox.ModAPI.IMyCubeGrid); var idx = Int32.Parse(prefabName); var cubeGrid = (Sandbox.ModAPI.IMyCubeGrid)entities.ToArray()[idx]; var grids = cubeGrid.GetAttachedGrids(); MyAPIGateway.Utilities.ShowMessage("Attached Count", string.Format("{0}", grids.Count)); //foreach (var grid in grids) // MyAPIGateway.Utilities.ShowMessage("Attached", string.Format("{0}", grid.EntityId)); return true; } //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. } #endregion #region test11 if (messageText.Equals("/test11", StringComparison.InvariantCultureIgnoreCase)) { //var identities = new List<IMyIdentity>(); //MyAPIGateway.Players.GetAllIdentites(identities); //var ident = identities.FirstOrDefault(); //var bIdent = ((IMyEntity)ident).GetObjectBuilder(); //MyAPIGateway.Utilities.ShowMessage("IMyIdentity", string.Format("{0}", bIdent.GetType())); var players = new List<IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p != null); var player = players.FirstOrDefault(); var cpnt = MyAPIGateway.Session.GetCheckpoint("null"); MyAPIGateway.Utilities.ShowMessage("cpnt", cpnt.Clients == null ? "null" : string.Format("{0}", cpnt.Clients.Count)); var c = MyAPIGateway.Session.GetWorld().Checkpoint.Clients; MyAPIGateway.Utilities.ShowMessage("Count", c == null ? "null" : string.Format("{0}", c.Count)); var nc = player.Client; MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType())); //MyAPIGateway.Utilities.ShowMessage("IMyNetworkClient", string.Format("{0}", nc.GetType().BaseType)); //var bPlayer = ((IMyEntity)nc).GetObjectBuilder(); //MyAPIGateway.Utilities.ShowMessage("IMyPlayer", string.Format("{0}", bPlayer.GetType())); //var vm = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, true); // most accurate for player view. return true; } #endregion #region test12 if (messageText.Equals("/test12", StringComparison.InvariantCultureIgnoreCase)) { var entity = Support.FindLookAtEntity(MyAPIGateway.Session.ControlledObject); var resultList = new List<ITerminalAction>(); if (entity != null) { var displayName = entity.DisplayName; MyAPIGateway.Utilities.ShowMessage("ID", displayName); MyAPIGateway.Utilities.ShowMessage("Components", string.Format("{0}", entity.Components == null)); MyAPIGateway.Utilities.ShowMessage("Hierarchy", string.Format("{0}", entity.Hierarchy == null)); var cockpits = entity.FindWorkingCockpits(); var terminal = (IMyTerminalBlock)cockpits[0]; //cockpits[0] terminal.GetActions(resultList); MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); } //Vector3D? FindFreePlace(Vector3D basePos, float radius, int maxTestCount = 20, int testsPerDistance = 5, float stepSize = 1f); //MyAPIGateway.Entities.FindFreePlace( //resultList.Clear(); //var myObject = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(typeof(MyObjectBuilder_Reactor), "SmallBlockLargeGenerator"); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(MyObjectBuilder_Reactor), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyMotorStator), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyFunctionalBlock), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); //MyAPIGateway.TerminalActionsHelper.GetActions(typeof(IMyTerminalBlock), resultList); //MyAPIGateway.Utilities.ShowMessage("count", string.Format("{0}", resultList.Count)); foreach (var a in resultList) { MyAPIGateway.Utilities.ShowMessage("item", string.Format("{0}={1}", a.Name, a.Id)); } return true; } #endregion #region test13 if (messageText.Equals("/test13", StringComparison.InvariantCultureIgnoreCase)) { var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); //var physicalItem = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(typeof(MyObjectBuilder_SpaceBall), "SpaceBallLarge")); //physicalItem.Public = true; //MyDefinitionManager.Static.EnvironmentDefinition.SmallShipMaxSpeed = 2000; //MyDefinitionManager.Static.EnvironmentDefinition.LargeShipMaxSpeed = 2000; MyAPIGateway.Session.GetCheckpoint("null").GameMode = MyGameModeEnum.Creative; //MyAPIGateway.Session.GetCheckpoint("null").CargoShipsEnabled //MyAPIGateway.Session.GetCheckpoint("null").EnableCopyPaste = true; //MyAPIGateway.Utilities.ShowMessage("Sun Distance", string.Format("{0}", MyDefinitionManager.Static.EnvironmentDefinition.DistanceToSun)); //MyDefinitionManager.Static.EnvironmentDefinition.DirectionToSun = new Vector3(0, 1, 0); foreach (var entity in entites) { var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid; if (cubeGrid != null) { var terminalsys = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(cubeGrid); //MyAPIGateway.Utilities.ShowMessage("Grid count", string.Format("{0} {1} {2}", cubeGrid.DisplayName, terminalsys.Blocks.Count, terminalsys.BlockGroups.Count)); //var blocks = new List<Sandbox.ModAPI.IMySlimBlock>(); //cubeGrid.GetBlocks(blocks, f => f.FatBlock != null && f.FatBlock == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity); //MyAPIGateway.Utilities.ShowMessage("Pilot count", string.Format("{0}", blocks.Count)); //cubeGrid.GetBlocks(blocks); //foreach (var block in blocks) //{ // cubeGrid.ColorBlocks(block.Position, block.Position, VRageMath.Color.Gold.ToHsvColor()); //} } } return true; } #endregion #region test14 // Tag every floating object in player GPS. if (messageText.Equals("/test14", StringComparison.InvariantCultureIgnoreCase)) { var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => (e is Sandbox.ModAPI.IMyFloatingObject)); foreach (var entity in entites) { var pos = entity.GetPosition(); var gps = MyAPIGateway.Session.GPS.Create("Floating " + entity.DisplayName, "Some drifting junk", pos, true, false); MyAPIGateway.Session.GPS.AddLocalGps(gps); } return true; } #endregion return false; }
public bool TryNamingAnBlockOrFloatingObject() { var worldMatrix = MyAPIGateway.Session.Camera.WorldMatrix; // most accurate for player view. var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f; var ray = new RayD(position, worldMatrix.Forward * 1000); var boundingSphere = new BoundingSphereD(worldMatrix.Translation, 30); var entites = MyEntities.GetEntitiesInSphere(ref boundingSphere); List <MyPhysics.HitInfo> hits = new List <MyPhysics.HitInfo>(); MyPhysics.CastRay(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 5, hits, 15); foreach (var hitInfo in hits) { var body = (MyPhysicsBody)hitInfo.HkHitInfo.Body.UserObject; if (body.Entity is MyFloatingObject) { var rayEntity = (MyEntity)body.Entity; NameDialog(rayEntity); return(true); } } foreach (var entity in entites) { var cubeGrid = entity as MyCubeGrid; if (cubeGrid != null && ray.Intersects(entity.PositionComp.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 100); if (hit.HasValue) { var block = cubeGrid.GetCubeBlock(hit.Value); if (block.FatBlock != null) { var dialog = new ValueGetScreenWithCaption("Name block dialog: " + block.FatBlock.DefinitionDisplayNameText, block.FatBlock.Name ?? block.FatBlock.DefinitionDisplayNameText + " has no name.", delegate(string text) { MyEntity foundEntity; if (MyEntities.TryGetEntityByName(text, out foundEntity)) { MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox( buttonType: MyMessageBoxButtonsType.OK, messageText: new StringBuilder("Entity with same name already exits, please enter different name."), messageCaption: new StringBuilder("Naming error"))); } else { block.FatBlock.Name = text; MyEntities.SetEntityName(block.FatBlock, true); return(true); } return(false); }); MyGuiSandbox.AddScreen(dialog); entites.Clear(); return(true); } } } } entites.Clear(); return(false); }
public static void FindLookAtEntity(IMyControllableEntity controlledEntity, out IMyEntity lookEntity, out double lookDistance, bool findShips = true, bool findPlayers = true, bool findAsteroids = true, bool findPlanets = true) { const float range = 5000000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; if (MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.Parent == null) { worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); } else { worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; // TODO: need to adjust for position of cockpit within ship. startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f); } //var worldMatrix = MyAPIGateway.Session.Player.PlayerCharacter.Entity.WorldMatrix; //var position = MyAPIGateway.Session.Player.PlayerCharacter.Entity.GetPosition(); //var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f + worldMatrix.Up * 1.0f; //MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", playerPos.X, playerPos.Y, playerPos.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z)); // The CameraController.GetViewMatrix appears warped at the moment. //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition(); //var worldMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix(); //var position = worldMatrix.Translation; //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z)); var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary<IMyEntity, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); foreach (var entity in entites) { if (findShips) { var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid; // check if the ray comes anywhere near the Grid before continuing. if (cubeGrid != null && ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (hit.HasValue) { var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); list.Add(entity, distance); } } } if (findPlayers) { var controller = entity as IMyControllableEntity; if (MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findAsteroids) { var voxelMap = entity as IMyVoxelMap; if (voxelMap != null) { var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2); var distance = (startPosition - center).Length(); // use distance to center of asteroid. list.Add(entity, distance); } } } if (findPlanets) { // Looks to be working against Git and public release. var planet = entity as Sandbox.Game.Entities.MyPlanet; if (planet != null) { var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = planet.PositionLeftBottomCorner + (planet.Size / 2); var distance = (startPosition - center).Length(); // use distance to center of planet. list.Add(entity, distance); } } } } if (list.Count == 0) { lookEntity = null; lookDistance = 0; return; } // find the closest Entity. var item = list.OrderBy(f => f.Value).First(); lookEntity = item.Key; lookDistance = item.Value; }
public void Update(List <IMyEntity> missileCollection) { if (SafetyTimerIsOver()) { ModDebugger.Launch(); // if (Missile.Physics.Flags != RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET; // float TURNING_SPEED = 0.1f; // float FACTOR = 2f; // Log.Info("Missile.Physics.Flags"); //BLEH Vector3 targetPoint = Vector3.Zero; try { Vector3 boundingBoxCenter = (Target.WorldAABB.Max + Target.WorldAABB.Min) * 0.5; if (boundingBoxCenter == Vector3.Zero) { boundingBoxCenter = Target.GetPosition(); } if (_hasPhysicsSteering) { Ray positiveVelocityRay = new Ray(Missile.GetPosition(), Missile.Physics.LinearVelocity); Ray negativeVelocityRay = new Ray(Missile.GetPosition(), -1f * Missile.Physics.LinearVelocity); Plane targetPlane = new Plane(boundingBoxCenter, Vector3.Normalize(Missile.Physics.LinearVelocity)); float?intersectionDist = positiveVelocityRay.Intersects(targetPlane); // Vector3 reverseVector; if (intersectionDist != null) { targetPoint = positiveVelocityRay.Position + (float)intersectionDist * positiveVelocityRay.Direction; // reverseVector = Target.GetPosition() - targetPoint; targetPoint = 2 * boundingBoxCenter - targetPoint; // targetPoint = targetPoint + reverseVector; } else { intersectionDist = negativeVelocityRay.Intersects(targetPlane); if (intersectionDist != null) { if ((_isOvershooting == false) && (_finishedOvershooting == false)) { _overshootDistance = Missile.Physics.LinearVelocity.Length() * (360 / _turningSpeed) / 10000 + 0; _isOvershooting = true; } // targetPoint = negativeVelocityRay.Position + (float)intersectionDist * negativeVelocityRay.Direction; if (_isOvershooting && !_finishedOvershooting) { if (intersectionDist > _overshootDistance) { targetPoint = boundingBoxCenter; _finishedOvershooting = true; // Log.Info("we finished overshooting, returning to target."); } else { targetPoint = Missile.GetPosition() + Missile.WorldMatrix.Forward; // Log.Info("we overshot, we keep heading forward."); // Log.Info(" current Distance: " + intersectionDist + " and overshootCorr " + _overshootDistance); } } else if (_isOvershooting && _finishedOvershooting) { targetPoint = boundingBoxCenter; } } } Vector3 diffVelocity = Target.GetTopMostParent().Physics.LinearVelocity - Missile.Physics.LinearVelocity; if (targetPoint == Vector3.Zero) { targetPoint = boundingBoxCenter - diffVelocity; } } else { targetPoint = boundingBoxCenter; } } catch (Exception e) { Log.Info("Caught exception during MissileData Update! " + e); if (Target != null) { targetPoint = Target.GetPosition(); } } Vector3 targetDirection = Vector3.Normalize(targetPoint - Missile.GetPosition()); float maxRadVelocity = MathHelper.ToRadians(_turningSpeed); float angle = MyUtils.GetAngleBetweenVectorsAndNormalise(Missile.WorldMatrix.Forward, targetDirection); // Log.Info("angle = " + MathHelper.ToDegrees(angle)); float turnPercent; if (Math.Abs(angle) < Double.Epsilon) { turnPercent = 0f; } else if (Math.Abs(angle) > maxRadVelocity) { turnPercent = maxRadVelocity / Math.Abs(angle); } else { turnPercent = 1f; } Matrix targetMatrix = Matrix.CreateWorld(Missile.GetPosition(), targetDirection, Vector3D.CalculatePerpendicularVector(targetDirection)); //Matrix.CreateFromYawPitchRoll(0f, (float)Math.PI*0.5f, 0f))); var slerpMatrix = Matrix.Slerp(Missile.WorldMatrix, targetMatrix, turnPercent); RayD nextTargetLineD = new RayD(Missile.GetPosition(), slerpMatrix.Forward); bool iswait = false; foreach (var othermissile in missileCollection) { if (othermissile.EntityId == Missile.EntityId) { continue; } if (nextTargetLineD.Intersects(othermissile.WorldVolume) != null) { iswait = true; } } if (iswait == false) { Missile.SetWorldMatrix(slerpMatrix); if (_hasPhysicsSteering) { var linVel = Missile.Physics.LinearVelocity; var linSpeed = linVel.Length(); Missile.Physics.LinearVelocity = 0.98f * linVel + 0.02f * Missile.WorldMatrix.Forward * linSpeed; } else { Vector3 linVel = Missile.Physics.LinearVelocity; Missile.Physics.LinearVelocity = Vector3.Normalize(Missile.WorldMatrix.Forward) * linVel.Length(); } } } else { // if (Missile.Physics.Flags == RigidBodyFlag.RBF_BULLET) Missile.Physics.Flags = RigidBodyFlag.RBF_BULLET & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE; } Tick(); }
public static void SpawnCargoShip(bool checkGravity) { Init( ); Wrapper.GameAction(() => { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Spawn cargo ship"); } // Select a spawn group to spawn MySpawnGroupDefinition spawnGroup = PickRandomSpawnGroup( ); if (spawnGroup == null) { return; } spawnGroup.ReloadPrefabs( ); 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) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("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) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Couldn't find free place for cargo spawn"); } 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); // 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; if (checkGravity) { //these point checks could be done in the trajectory intersect, but checking points is faster than ray intersect if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipPosition, spawnGroup.SpawnRadius)) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Failed to spawn cargo ship: Spawn location is in gravity well"); } return; } if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipDestination, spawnGroup.SpawnRadius)) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Failed to spawn cargo ship: Destination is in gravity well"); } } if (MyGravityProviderSystem.DoesTrajectoryIntersectNaturalGravity(shipPosition, shipDestination, spawnGroup.SpawnRadius + 500)) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects gravity well"); } return; } } MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); if (m_raycastHits.Count > 0) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects another object"); } 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.CollisionLayers.ObjectDetectionCollisionLayer); if (m_raycastHits.Count > 0) { if (ExtenderOptions.IsDebugging) { Essentials.Log.Info("Failed to spawn cargo ship: Ship path intersects another object"); } return; } } } long spawnGroupId = MyPirateAntennas.GetPiratesId( ); // The ships were collision-free. Now spawn them foreach (var shipPrefab in spawnGroup.Prefabs) { // 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( ); // CH: We don't want a new identity for each ship anymore. We should handle that in a better way... /*if (shipPrefab.ResetOwnership) * { * if (spawnGroupId == 0) * { * //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"); * spawnGroupId = spawnGroupIdentity.IdentityId; * } * }*/ // Deploy ship MyPrefabManager.Static.SpawnPrefab( resultList: m_tmpGridList, prefabName: shipPrefab.SubtypeId, position: shipPosition, forward: direction, up: up, initialLinearVelocity: shipPrefab.Speed * direction, beaconName: shipPrefab.BeaconText, spawningOptions: VRage.Game.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection | VRage.Game.ModAPI.SpawningOptions.SpawnRandomCargo | VRage.Game.ModAPI.SpawningOptions.DisableDampeners, ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0, updateSync: true); /* * foreach (var grid in m_tmpGridList) * { * var cockpit = grid.GetFirstBlockOfType<MyCockpit>(); * if (cockpit != null) * { * MySimpleAutopilot ai = new MySimpleAutopilot(shipDestination, (Vector3)direction); * cockpit.AttachAutopilot(ai); * break; * } * } */ m_tmpGridList.Clear( ); } }); }
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.TestPlaceInSpace(origin.Value, spawnGroup.SpawnRadius); if (!origin.HasValue) { if (++m_eventSpawnTry <= EVENT_SPAWN_TRY_MAX) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships - no free place found. Try " + m_eventSpawnTry + " of " + EVENT_SPAWN_TRY_MAX); MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } else { m_eventSpawnTry = 0; return; } } m_eventSpawnTry = 0; // 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; //these point checks could be done in the trajectory intersect, but checking points is faster than ray intersect if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipPosition, spawnGroup.SpawnRadius)) { if (!MyFinalBuildConstants.IS_OFFICIAL) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships: spawn point is inside gravity well"); } MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } if (MyGravityProviderSystem.IsPositionInNaturalGravity(shipDestination, spawnGroup.SpawnRadius)) { if (!MyFinalBuildConstants.IS_OFFICIAL) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships: destination point is inside gravity well"); } MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } if (MyGravityProviderSystem.DoesTrajectoryIntersectNaturalGravity(shipPosition, shipDestination, spawnGroup.SpawnRadius + NEUTRAL_SHIP_SPAWN_OFFSET)) { if (!MyFinalBuildConstants.IS_OFFICIAL) { MySandboxGame.Log.WriteLine("Could not spawn neutral ships: flight path intersects gravity well"); } MyGlobalEvents.RescheduleEvent(senderEvent as MyGlobalEventBase, NEUTRAL_SHIP_RESCHEDULE_TIME); ProfilerShort.End(); return; } MyPhysics.CastRay(shipPosition, shipDestination, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); if (m_raycastHits.Count > 0) { if (!MyFinalBuildConstants.IS_OFFICIAL) { 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.CollisionLayers.ObjectDetectionCollisionLayer); if (m_raycastHits.Count > 0) { if (!MyFinalBuildConstants.IS_OFFICIAL) { 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"); long spawnGroupId = MyPirateAntennas.GetPiratesId(); // 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); List <MyCubeGrid> tmpGridList = new List <MyCubeGrid>(); // CH: We don't want a new identity for each ship anymore. We should handle that in a better way... /*if (shipPrefab.ResetOwnership) * { * if (spawnGroupId == 0) * { * //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"); * spawnGroupId = spawnGroupIdentity.IdentityId; * } * }*/ // Deploy ship ProfilerShort.Begin("Spawn cargo ship"); Stack <Action> callbacks = new Stack <Action>(); callbacks.Push(delegate() { InitAutopilot(tmpGridList, shipDestination, direction); foreach (var grid in tmpGridList) { Debug.Assert(grid.Physics.Enabled); grid.ActivatePhysics(); //last chance to activate physics } }); MyPrefabManager.Static.SpawnPrefab( resultList: tmpGridList, prefabName: shipPrefab.SubtypeId, position: shipPosition, forward: direction, up: up, initialLinearVelocity: shipPrefab.Speed * direction, beaconName: shipPrefab.BeaconText, spawningOptions: VRage.Game.ModAPI.SpawningOptions.RotateFirstCockpitTowardsDirection | VRage.Game.ModAPI.SpawningOptions.SpawnRandomCargo | VRage.Game.ModAPI.SpawningOptions.DisableDampeners, ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0, callbacks: callbacks); ProfilerShort.End(); ProfilerShort.End(); } ProfilerShort.End(); }
public static ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group> FindLookAtGridGroup(IMyCharacter controlledEntity) { const float range = 5000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); var list = new Dictionary <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); foreach (var group in MyCubeGridGroups.Static.Physical.Groups) { foreach (MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Node groupNodes in group.Nodes) { IMyCubeGrid cubeGrid = groupNodes.NodeData; if (cubeGrid == null) { continue; } if (cubeGrid.Physics == null) { continue; } // check if the ray comes anywhere near the Grid before continuing. if (!ray.Intersects(cubeGrid.WorldAABB).HasValue) { continue; } Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (!hit.HasValue) { continue; } double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); if (list.TryGetValue(group, out double oldDistance)) { if (distance < oldDistance) { list.Remove(group); list.Add(group, distance); } } else { list.Add(group, distance); } } } var bag = new ConcurrentBag <MyGroups <MyCubeGrid, MyGridPhysicalGroupData> .Group>(); if (list.Count == 0) { return(bag); } // find the closest Entity. var item = list.OrderBy(f => f.Value).First(); bag.Add(item.Key); return(bag); }
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.CollisionLayers.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.CollisionLayers.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"); long spawnGroupId = MyPirateAntennas.GetPiratesId(); // 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(); // CH: We don't want a new identity for each ship anymore. We should handle that in a better way... /*if (shipPrefab.ResetOwnership) { if (spawnGroupId == 0) { //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"); spawnGroupId = spawnGroupIdentity.IdentityId; } }*/ // 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, ownerId: shipPrefab.ResetOwnership ? spawnGroupId : 0, updateSync: true); ProfilerShort.End(); foreach (var grid in m_tmpGridList) { 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 static void AcquireProjectile(Weapon w, out TargetType targetType) { var ai = w.Comp.Ai; var s = w.System; var physics = s.Session.Physics; var target = w.NewTarget; var weaponPos = w.MyPivotPos; var collection = ai.GetProCache(); var numOfTargets = collection.Count; var lockedOnly = w.System.Values.Targeting.LockedSmartOnly; var smartOnly = w.System.Values.Targeting.IgnoreDumbProjectiles; if (s.ClosestFirst) { int length = collection.Count; for (int h = length / 2; h > 0; h /= 2) { for (int i = h; i < length; i += 1) { var tempValue = collection[i]; double temp; Vector3D.DistanceSquared(ref collection[i].Position, ref weaponPos, out temp); int j; for (j = i; j >= h && Vector3D.DistanceSquared(collection[j - h].Position, weaponPos) > temp; j -= h) { collection[j] = collection[j - h]; } collection[j] = tempValue; } } } var numToRandomize = s.ClosestFirst ? w.System.Values.Targeting.TopTargets : numOfTargets; var deck = GetDeck(ref target.TargetDeck, ref target.TargetPrevDeckLen, 0, numOfTargets, numToRandomize, w.TargetData.WeaponRandom, Acquire); for (int x = 0; x < numOfTargets; x++) { var card = deck[x]; var lp = collection[card]; var cube = lp.Info.Target.Entity as MyCubeBlock; if (smartOnly && !lp.SmartsOn || lockedOnly && (!lp.SmartsOn || cube != null && cube.CubeGrid.IsSameConstructAs(w.Comp.Ai.MyGrid)) || lp.MaxSpeed > s.MaxTargetSpeed || lp.MaxSpeed <= 0 || lp.State != Projectile.ProjectileState.Alive || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) > w.MaxTargetDistanceSqr || Vector3D.DistanceSquared(lp.Position, w.MyPivotPos) < w.MinTargetDistanceSqr) { continue; } Vector3D predictedPos; if (Weapon.CanShootTarget(w, ref lp.Position, lp.Velocity, lp.AccelVelocity, out predictedPos)) { var needsCast = false; for (int i = 0; i < ai.Obstructions.Count; i++) { var ent = ai.Obstructions[i]; var obsSphere = ent.PositionComp.WorldVolume; var dir = lp.Position - weaponPos; var beam = new RayD(ref weaponPos, ref dir); if (beam.Intersects(obsSphere) != null) { var transform = ent.PositionComp.WorldMatrixRef; var box = ent.PositionComp.LocalAABB; var obb = new MyOrientedBoundingBoxD(box, transform); if (obb.Intersects(ref beam) != null) { needsCast = true; break; } } } if (needsCast) { IHitInfo hitInfo; physics.CastRay(weaponPos, lp.Position, out hitInfo, 15); if (hitInfo?.HitEntity == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf())) { double hitDist; Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist); var shortDist = hitDist; var origDist = hitDist; const long topEntId = long.MaxValue; target.Set(null, lp.Position, shortDist, origDist, topEntId, lp); targetType = TargetType.Projectile; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } } else { Vector3D?hitInfo; if (GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref lp.Position, out hitInfo, w.Comp.MyCube, w.Comp.Ai)) { continue; } double hitDist; Vector3D.Distance(ref weaponPos, ref lp.Position, out hitDist); var shortDist = hitDist; var origDist = hitDist; const long topEntId = long.MaxValue; target.Set(null, lp.Position, shortDist, origDist, topEntId, lp); targetType = TargetType.Projectile; target.TransferTo(w.Target, w.Comp.Session.Tick); return; } } } targetType = TargetType.None; }
public static List <MyCubeGrid> FindLookAtGridGroup(IMyCharacter controlledEntity, long playerId, out CheckResult result) { const float range = 5000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; var GridsGroup = new List <MyCubeGrid>(); var charlocation = controlledEntity.PositionComp.GetPosition(); var sphere = new BoundingSphereD(charlocation, range); var entList = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere); if (entList == null || entList.Count == 0) { result = CheckResult.GRID_NOT_FOUND; return(GridsGroup); } worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); var list = new Dictionary <MyCubeGrid, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); var FoundWrongOwner = false; foreach (var ent in entList) { if (ent is MyCubeGrid cubeGrid) { if (cubeGrid.Physics != null) { // check if the ray comes anywhere near the Grid before continuing. if (ray.Intersects(cubeGrid.PositionComp.WorldAABB).HasValue) { Vector3I?hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (hit.HasValue) { /* We are not the server and playerId is not owner */ if (playerId != 0 && !OwnershipCorrect(cubeGrid, playerId)) { FoundWrongOwner = true; continue; } double distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); if (list.TryGetValue(cubeGrid, out double oldDistance)) { if (distance < oldDistance) { list.Remove(cubeGrid); list.Add(cubeGrid, distance); } } else { list.Add(cubeGrid, distance); } } } } } } // find the closest Entity. if (list != null && list.Any()) { var grid = list.OrderBy(f => f.Value).First().Key; // only here we can see attached by landing gear grids to main grid! var IMygrids = new List <IMyCubeGrid>(); MyAPIGateway.GridGroups.GetGroup(grid, GridLinkTypeEnum.Physical, IMygrids); // convert back to MyCubeGrid foreach (var Mygrid in IMygrids) { GridsGroup.Add((MyCubeGrid)Mygrid); } // sort the list. largest to smallest GridsGroup.SortNoAlloc((x, y) => x.BlocksCount.CompareTo(y.BlocksCount)); GridsGroup.Reverse(); GridsGroup.SortNoAlloc((x, y) => x.GridSizeEnum.CompareTo(y.GridSizeEnum)); result = CheckResult.OK; return(GridsGroup); } if (FoundWrongOwner) { result = CheckResult.OWNED_BY_DIFFERENT_PLAYER; } else { result = CheckResult.GRID_NOT_FOUND; } return(GridsGroup); }
/// <summary> /// Gets a destination and tries to fix it so that it does not collide with anything /// </summary> /// <param name="originalDestination">The final destination that the remote wants to get to.</param> /// <param name="checkRadius">The maximum radius until which this method should search.</param> /// <param name="shipRadius">The radius of our ship. Make sure that this is large enough to avoid collision.</param> Vector3D ModAPI.Ingame.IMyRemoteControl.GetFreeDestination(Vector3D originalDestination, float checkRadius, float shipRadius) { MyCestmirDebugInputComponent.ClearDebugSpheres(); MyCestmirDebugInputComponent.ClearDebugPoints(); MyCestmirDebugInputComponent.AddDebugPoint(this.WorldMatrix.Translation, Color.Green); Vector3D retval = originalDestination; BoundingSphereD sphere = new BoundingSphereD(this.WorldMatrix.Translation, shipRadius + checkRadius); Vector3D rayDirection = originalDestination - this.WorldMatrix.Translation; double originalDistance = rayDirection.Length(); rayDirection = rayDirection / originalDistance; RayD ray = new RayD(this.WorldMatrix.Translation, rayDirection); double closestIntersection = double.MaxValue; BoundingSphereD closestSphere = default(BoundingSphereD); var entities = MyEntities.GetEntitiesInSphere(ref sphere); for (int i = 0; i < entities.Count; ++i) { var entity = entities[i]; if (!(entity is MyCubeGrid) && !(entity is MyVoxelMap)) continue; if (entity.Parent != null) continue; if (entity == this.Parent) continue; BoundingSphereD entitySphere = entity.PositionComp.WorldVolume; entitySphere.Radius += shipRadius; MyCestmirDebugInputComponent.AddDebugSphere(entitySphere.Center, (float)entity.PositionComp.WorldVolume.Radius, Color.Plum); MyCestmirDebugInputComponent.AddDebugSphere(entitySphere.Center, (float)entity.PositionComp.WorldVolume.Radius + shipRadius, Color.Purple); double? intersection = ray.Intersects(entitySphere); if (intersection.HasValue && intersection.Value < closestIntersection) { closestIntersection = intersection.Value; closestSphere = entitySphere; } } if (closestIntersection != double.MaxValue) { Vector3D correctedDestination = ray.Position + closestIntersection * ray.Direction; MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination, 1.0f, Color.Blue); Vector3D normal = correctedDestination - closestSphere.Center; if (Vector3D.IsZero(normal)) { normal = Vector3D.Up; } normal.Normalize(); MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination + normal, 1.0f, Color.Red); Vector3D newDirection = Vector3D.Reject(ray.Direction, normal); newDirection.Normalize(); newDirection *= Math.Max(20.0, closestSphere.Radius * 0.5); MyCestmirDebugInputComponent.AddDebugSphere(correctedDestination + newDirection, 1.0f, Color.LightBlue); retval = correctedDestination + newDirection; } else { retval = ray.Position + ray.Direction * Math.Min(checkRadius, originalDistance); } entities.Clear(); return retval; }
public bool TryNamingAnBlockOrFloatingObject() { var worldMatrix = MyAPIGateway.Session.Camera.WorldMatrix; // most accurate for player view. var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f; var ray = new RayD(position, worldMatrix.Forward * 1000); var boundingSphere = new BoundingSphereD(worldMatrix.Translation, 30); var entites = MyEntities.GetEntitiesInSphere(ref boundingSphere); List<MyPhysics.HitInfo> hits = new List<MyPhysics.HitInfo>(); MyPhysics.CastRay(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 5, hits, 15); foreach (var hitInfo in hits) { var body = (MyPhysicsBody)hitInfo.HkHitInfo.Body.UserObject; if (body.Entity is MyFloatingObject) { var rayEntity = (MyEntity) body.Entity; NameDialog(rayEntity); return true; } } foreach (var entity in entites) { var cubeGrid = entity as MyCubeGrid; if (cubeGrid != null && ray.Intersects(entity.PositionComp.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(worldMatrix.Translation, worldMatrix.Translation + worldMatrix.Forward * 100); if (hit.HasValue) { var block = cubeGrid.GetCubeBlock(hit.Value); if(block.FatBlock != null) { var dialog = new ValueGetScreenWithCaption("Name block dialog: " + block.FatBlock.DefinitionDisplayNameText, block.FatBlock.Name ?? block.FatBlock.DefinitionDisplayNameText + " has no name.", delegate(string text) { MyEntity foundEntity; if (MyEntities.TryGetEntityByName(text, out foundEntity)) { MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox( buttonType: MyMessageBoxButtonsType.OK, messageText: new StringBuilder("Entity with same name already exits, please enter different name."), messageCaption: new StringBuilder("Naming error"))); } else { block.FatBlock.Name = text; MyEntities.SetEntityName(block.FatBlock, true); return true; } return false; }); MyGuiSandbox.AddScreen(dialog); entites.Clear(); return true; } } } } entites.Clear(); return false; }
internal static Vector3D?ProcessVoxel(LineD trajectile, MyVoxelBase voxel, WeaponSystem system, List <Vector3I> testPoints) { var planet = voxel as MyPlanet; var voxelMap = voxel as MyVoxelMap; var ray = new RayD(trajectile.From, trajectile.Direction); var voxelAABB = voxel.PositionComp.WorldAABB; var rayVoxelDist = ray.Intersects(voxelAABB); if (rayVoxelDist.HasValue) { var voxelMaxLen = voxel.PositionComp.WorldVolume.Radius * 2; var start = trajectile.From + (ray.Direction * rayVoxelDist.Value); var lenRemain = trajectile.Length - rayVoxelDist.Value; var end = voxelMaxLen > lenRemain ? start + (ray.Direction * lenRemain) : start + (ray.Direction * voxelMaxLen); var testLine = new LineD(trajectile.From + (ray.Direction * rayVoxelDist.Value), end); var rotMatrix = Quaternion.CreateFromRotationMatrix(voxel.WorldMatrix); var obb = new MyOrientedBoundingBoxD(voxel.PositionComp.WorldAABB.Center, voxel.PositionComp.LocalAABB.HalfExtents, rotMatrix); if (obb.Intersects(ref testLine) != null) { Log.Line("obb"); if (planet != null) { var startPos = trajectile.From - planet.PositionLeftBottomCorner; var startInt = Vector3I.Round(startPos); var endPos = trajectile.To - planet.PositionLeftBottomCorner; var endInt = Vector3I.Round(endPos); BresenhamLineDraw(startInt, endInt, testPoints); for (int i = 0; i < testPoints.Count; ++i) { var voxelCoord = testPoints[i]; var voxelHit = new VoxelHit(); planet.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (voxelHit.HasHit) { return((Vector3D)voxelCoord + planet.PositionLeftBottomCorner); } } } else if (voxelMap != null) { var startPos = trajectile.From - voxelMap.PositionLeftBottomCorner; var startInt = Vector3I.Round(startPos); var endPos = trajectile.To - voxelMap.PositionLeftBottomCorner; var endInt = Vector3I.Round(endPos); BresenhamLineDraw(startInt, endInt, testPoints); for (int i = 0; i < testPoints.Count; ++i) { var voxelCoord = testPoints[i]; var voxelHit = new VoxelHit(); voxelMap.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (voxelHit.HasHit) { return((Vector3D)voxelCoord + voxelMap.PositionLeftBottomCorner); } } } } } return(null); }
public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable) { const float range = 5000000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; IMyCubeGrid occupiedGrid = null; if (controlledEntity.Entity.Parent == null) { worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); } else { occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid; worldMatrix = controlledEntity.Entity.WorldMatrix; // TODO: need to adjust for position of cockpit within ship. startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f); } //var worldMatrix = MyAPIGateway.Session.Player.PlayerCharacter.Entity.WorldMatrix; //var position = MyAPIGateway.Session.Player.PlayerCharacter.Entity.GetPosition(); //var position = worldMatrix.Translation + worldMatrix.Forward * 0.5f + worldMatrix.Up * 1.0f; //MyAPIGateway.Utilities.ShowMessage("Pos", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", playerPos.X, playerPos.Y, playerPos.Z, playerMatrix.Forward.X, playerMatrix.Forward.Y, playerMatrix.Forward.Z)); // The CameraController.GetViewMatrix appears warped at the moment. //var position = ((IMyEntity)MyAPIGateway.Session.CameraController).GetPosition(); //var worldMatrix = MyAPIGateway.Session.CameraController.GetViewMatrix(); //var position = worldMatrix.Translation; //MyAPIGateway.Utilities.ShowMessage("Cam", string.Format("x={0:N},y={1:N},z={2:N} x={3:N},y={4:N},z={5:N}", position.X, position.Y, position.Z, worldMatrix.Forward.X, worldMatrix.Forward.Y, worldMatrix.Forward.Z)); var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary<IMyEntity, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); foreach (var entity in entites) { if (findShips || findCubes) { var cubeGrid = entity as Sandbox.ModAPI.IMyCubeGrid; if (cubeGrid != null) { if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId) continue; // TODO: ignore construction. New cube, new ship, new station, new paste. //if (ignoreConstruction && (MyAPIGateway.CubeBuilder.BlockCreationIsActivated || MyAPIGateway.CubeBuilder.ShipCreationIsActivated || MyAPIGateway.CubeBuilder.CopyPasteIsActivated)) // continue; // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste. // TODO: need a better way of determining projection other than Physics, as constructions have no physics either.. if (ignoreProjection && cubeGrid.Physics == null) continue; // check if the ray comes anywhere near the Grid before continuing. if (ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (hit.HasValue) { var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); var block = cubeGrid.GetCubeBlock(hit.Value); if (block.FatBlock != null && findCubes) list.Add(block.FatBlock, distance); else if (findShips) list.Add(entity, distance); } } } } if (findPlayers) { var controller = entity as IMyControllableEntity; if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findReplicable) { var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity; if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findAsteroids) { var voxelMap = entity as IMyVoxelMap; if (voxelMap != null) { var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { Vector3D? hitIngoing; Vector3D? hitOutgoing; // May not be asteroid that is blocking ray, so am doing additional checks. It's still not reliable. if (voxelMap.WorldAABB.IntersectPoints(startPosition, endPosition, out hitIngoing, out hitOutgoing) && Sandbox.Game.Entities.MyEntities.IsRaycastBlocked(hitIngoing.Value, hitOutgoing.Value)) { Vector3 lastOutsidePos; // TODO: IsInsideVoxel doesn't appear to be reliable. Need to find an improved method. //List<Sandbox.Engine.Physics.MyPhysics.HitInfo> m_hits = new List<Sandbox.Engine.Physics.MyPhysics.HitInfo>(); //Sandbox.Engine.Physics.MyPhysics.CastRay(startPosition, endPosition, m_hits, 0); // MyPhysics is not whitelisted. if (Sandbox.Game.Entities.MyEntities.IsInsideVoxel(startPosition, endPosition, out lastOutsidePos)) { list.Add(entity, Vector3D.Distance(startPosition, lastOutsidePos)); //MyAPIGateway.Utilities.ShowMessage("Range", "CheckA"); } else { var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2); // use distance to center of asteroid as an approximation. //MyAPIGateway.Utilities.ShowMessage("Range", "CheckB"); list.Add(entity, Vector3D.Distance(startPosition, center)); } } } } } if (findPlanets) { // Looks to be working against Git and public release. var planet = entity as Sandbox.Game.Entities.MyPlanet; if (planet != null) { var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = planet.WorldMatrix.Translation; var distance = (startPosition - center).Length(); // use distance to center of planet. list.Add(entity, distance); } } } } if (list.Count == 0) { lookEntity = null; lookDistance = 0; hitPoint = Vector3D.Zero; return; } // find the closest Entity. var item = list.OrderBy(f => f.Value).First(); lookEntity = item.Key; lookDistance = item.Value; hitPoint = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance); }
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(); }
public static void FindLookAtEntity(IMyControllableEntity controlledEntity, bool ignoreOccupiedGrid, bool ignoreProjection, out IMyEntity lookEntity, out double lookDistance, out Vector3D hitPoint, bool findShips, bool findCubes, bool findPlayers, bool findAsteroids, bool findPlanets, bool findReplicable) { const float range = 5000000; Matrix worldMatrix; Vector3D startPosition; Vector3D endPosition; IMyCubeGrid occupiedGrid = null; if (controlledEntity.Entity.Parent == null) { worldMatrix = controlledEntity.GetHeadMatrix(true, true, false); // dead center of player cross hairs, or the direction the player is looking with ALT. startPosition = worldMatrix.Translation + worldMatrix.Forward * 0.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 0.5f); } else { occupiedGrid = controlledEntity.Entity.GetTopMostParent() as IMyCubeGrid; worldMatrix = controlledEntity.Entity.WorldMatrix; // TODO: need to adjust for position of cockpit within ship. startPosition = worldMatrix.Translation + worldMatrix.Forward * 1.5f; endPosition = worldMatrix.Translation + worldMatrix.Forward * (range + 1.5f); } var entites = new HashSet<IMyEntity>(); MyAPIGateway.Entities.GetEntities(entites, e => e != null); var list = new Dictionary<IMyEntity, double>(); var ray = new RayD(startPosition, worldMatrix.Forward); foreach (var entity in entites) { if (findShips || findCubes) { var cubeGrid = entity as IMyCubeGrid; if (cubeGrid != null) { if (ignoreOccupiedGrid && occupiedGrid != null && occupiedGrid.EntityId == cubeGrid.EntityId) continue; // Will ignore Projected grids, new grid/cube placement, and grids in middle of copy/paste. if (ignoreProjection && cubeGrid.Physics == null) continue; // check if the ray comes anywhere near the Grid before continuing. if (ray.Intersects(entity.WorldAABB).HasValue) { var hit = cubeGrid.RayCastBlocks(startPosition, endPosition); if (hit.HasValue) { var distance = (startPosition - cubeGrid.GridIntegerToWorld(hit.Value)).Length(); var block = cubeGrid.GetCubeBlock(hit.Value); if (block.FatBlock != null && findCubes) list.Add(block.FatBlock, distance); else if (findShips) list.Add(entity, distance); } } } } if (findPlayers) { var controller = entity as IMyControllableEntity; if (controlledEntity.Entity.EntityId != entity.EntityId && controller != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findReplicable) { var replicable = entity as Sandbox.Game.Entities.MyInventoryBagEntity; if (replicable != null && ray.Intersects(entity.WorldAABB).HasValue) { var distance = (startPosition - entity.GetPosition()).Length(); list.Add(entity, distance); } } if (findAsteroids) { var voxelMap = entity as IMyVoxelMap; if (voxelMap != null) { var aabb = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.Storage.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = voxelMap.PositionLeftBottomCorner + (voxelMap.Storage.Size / 2); var distance = (startPosition - center).Length(); // use distance to center of asteroid. list.Add(entity, distance); } } } if (findPlanets) { // Looks to be working against Git and public release. var planet = entity as Sandbox.Game.Entities.MyPlanet; if (planet != null) { var aabb = new BoundingBoxD(planet.PositionLeftBottomCorner, planet.PositionLeftBottomCorner + planet.Size); var hit = ray.Intersects(aabb); if (hit.HasValue) { var center = planet.WorldMatrix.Translation; var distance = (startPosition - center).Length(); // use distance to center of planet. list.Add(entity, distance); } } } } if (list.Count == 0) { lookEntity = null; lookDistance = 0; hitPoint = Vector3D.Zero; return; } // find the closest Entity. var item = list.OrderBy(f => f.Value).First(); lookEntity = item.Key; lookDistance = item.Value; hitPoint = startPosition + (Vector3D.Normalize(ray.Direction) * lookDistance); }