//alter position based on altitude private void HoverMechanic(ref Vector3D pos) { m_hoverMin = 5; m_hoverMax = 25; Vector3 gravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(pos); if (gravity.LengthSquared() > 0f) { MyPlanet planet = MyGamePruningStructure.GetClosestPlanet(pos); if (planet != null) { Vector3D closestPoint = planet.GetClosestSurfacePointGlobal(ref pos); float altitude = (float)Vector3D.Distance(closestPoint, pos); if (Vector3D.DistanceSquared(planet.PositionComp.GetPosition(), closestPoint) > Vector3D.DistanceSquared(planet.PositionComp.GetPosition(), pos)) { altitude *= -1; } if (altitude < m_hoverMin) { pos = closestPoint - Vector3D.Normalize(gravity) * m_hoverMin; } else if (altitude > m_hoverMax) { pos = closestPoint - Vector3D.Normalize(gravity) * m_hoverMax; } } } }
/// <summary> /// Checks if a position on a planet is underground /// </summary> public static bool IsUnderGround(MyPlanet planet, Vector3D position, double altitudeOffset = 0) { if (planet == null) { return(false); } double altitude = (position - planet.WorldMatrix.Translation).Length() + altitudeOffset; if (altitude < planet.MinimumRadius) { return(true); } if (altitude > planet.MaximumRadius) { return(false); } if ((altitude - (planet.GetClosestSurfacePointGlobal(position) - planet.WorldMatrix.Translation).Length()) < 0) { return(true); } return(false); }
public override void UpdateAfterSimulation() { if (Tick % 5 == 0) { if (Camera == null) { return; } rainImpactEntities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref frustumBBox, rainImpactEntities); //MyAPIGateway.Parallel.Start(CalculateLines); CalculateLines(); } if (Tick % 60 == 0 && closestPlanet != null) { cameraDistanceFromSurface = closestPlanet.GetClosestSurfacePointGlobal(Camera.Position); cameraAltitude = (Camera.Position - cameraDistanceFromSurface).Length(); } if (Tick % 301 == 0) { closestPlanet = MyGamePruningStructure.GetClosestPlanet(Camera.Position); if (closestPlanet != null) { planetCentre = closestPlanet.PositionComp.WorldAABB.Center; } } lines.Clear(); }
private void SpawnBot(SpawnInfo spawnInfo, MyPlanet planet, MyPlanetAnimalSpawnInfo animalSpawnInfo) { PlanetAIInfo planetInfo = null; if (!m_planets.TryGetValue(planet.EntityId, out planetInfo)) { Debug.Assert(false, "Could not get planet info!"); return; } if (planetInfo.BotNumber >= MAX_BOTS_PER_PLANET) { return; } Debug.Assert(animalSpawnInfo != null); double spawnDistMin = animalSpawnInfo.SpawnDistMin; double spawnDistMax = animalSpawnInfo.SpawnDistMax; Vector3D center = spawnInfo.Position; Vector3D planetGravityVec = MyGravityProviderSystem.CalculateNaturalGravityInPoint(center); //GR: if gravity is zero provide a random Vector to normalize if (planetGravityVec == Vector3D.Zero) { planetGravityVec = Vector3D.Up; } planetGravityVec.Normalize(); Vector3D planetTangent = Vector3D.CalculatePerpendicularVector(planetGravityVec); Vector3D planetBitangent = Vector3D.Cross(planetGravityVec, planetTangent); planetTangent.Normalize(); planetBitangent.Normalize(); Vector3D spawnPos = MyUtils.GetRandomDiscPosition(ref center, spawnDistMin, spawnDistMax, ref planetTangent, ref planetBitangent); spawnPos = planet.GetClosestSurfacePointGlobal(ref spawnPos); Vector3D?spawnPosCorrected = MyEntities.FindFreePlace(spawnPos, 2.0f); if (spawnPosCorrected.HasValue) { spawnPos = spawnPosCorrected.Value; } planet.CorrectSpawnLocation(ref spawnPos, 2.0f); MyAgentDefinition botBehavior = GetAnimalDefinition(animalSpawnInfo) as MyAgentDefinition; if (botBehavior != null) { if (botBehavior.Id.SubtypeName == Wolf_SUBTYPE_ID && MySession.Static.EnableWolfs) { MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos); } else if (botBehavior.Id.SubtypeName != Wolf_SUBTYPE_ID && MySession.Static.EnableSpiders) { MyAIComponent.Static.SpawnNewBot(botBehavior, spawnPos); } } }
internal static bool CheckSurfacePointsOnLine(MyPlanet planet, ref LineD testLine, double distBetweenPoints) { var checkPoints = (int)((testLine.Length / distBetweenPoints) + distBetweenPoints); var lastPoint = (checkPoints - 1); for (int i = 0; i < checkPoints; i++) { var planetInPath = i != lastPoint; var extend = (distBetweenPoints * i); if (extend > testLine.Length) { extend = testLine.Length; } var testPos = testLine.From + (testLine.Direction * extend); if (planetInPath) { var closestSurface = planet.GetClosestSurfacePointGlobal(ref testPos); double surfaceDistToTest; Vector3D.DistanceSquared(ref closestSurface, ref testPos, out surfaceDistToTest); if (surfaceDistToTest < 4) { return(true); } } if (!planetInPath) { var closestSurface = planet.GetClosestSurfacePointGlobal(ref testPos); var reverseLine = testLine; reverseLine.Direction = -reverseLine.Direction; reverseLine.From = testPos; double closestRevDist; Vector3D.Distance(ref closestSurface, ref reverseLine.From, out closestRevDist); reverseLine.To = reverseLine.From + (reverseLine.Direction * (closestRevDist + distBetweenPoints)); Vector3D?voxelHit; planet.GetIntersectionWithLine(ref reverseLine, out voxelHit); return(voxelHit.HasValue); } } return(false); }
internal void MyPlanetInfo(bool clear = false) { if (!clear) { MyPlanet = MyPlanetTmp; var gridVolume = MyGrid.PositionComp.WorldVolume; var gridRadius = gridVolume.Radius; var gridCenter = gridVolume.Center; var planetCenter = MyPlanet.PositionComp.WorldAABB.Center; ClosestPlanetSqr = double.MaxValue; if (new BoundingSphereD(planetCenter, MyPlanet.AtmosphereRadius + gridRadius).Intersects(gridVolume)) { InPlanetGravity = true; PlanetClosestPoint = MyPlanet.GetClosestSurfacePointGlobal(gridCenter); ClosestPlanetCenter = planetCenter; double pointDistSqr; Vector3D.DistanceSquared(ref PlanetClosestPoint, ref gridCenter, out pointDistSqr); pointDistSqr -= (gridRadius * gridRadius); if (pointDistSqr < 0) { pointDistSqr = 0; } ClosestPlanetSqr = pointDistSqr; PlanetSurfaceInRange = pointDistSqr <= MaxTargetingRangeSqr; TouchingWater = Session.WaterApiLoaded && GridTouchingWater(); } else { InPlanetGravity = false; PlanetClosestPoint = MyPlanet.GetClosestSurfacePointGlobal(gridCenter); ClosestPlanetCenter = planetCenter; double pointDistSqr; Vector3D.DistanceSquared(ref PlanetClosestPoint, ref gridCenter, out pointDistSqr); pointDistSqr -= (gridRadius * gridRadius); if (pointDistSqr < 0) { pointDistSqr = 0; } ClosestPlanetSqr = pointDistSqr; TouchingWater = false; } } else { MyPlanet = null; PlanetClosestPoint = Vector3D.Zero; PlanetSurfaceInRange = false; InPlanetGravity = false; ClosestPlanetSqr = double.MaxValue; TouchingWater = false; } }
/// <summary> /// Checks if a position on a planet is underground /// </summary> public static double GetAltitude(MyPlanet planet, Vector3D position, double altitudeOffset = 0) { double altitude = (position - planet.WorldMatrix.Translation).Length() + altitudeOffset; if (altitude < planet.MinimumRadius || altitude > planet.MaximumRadius) { return(altitude); } return(altitude - (planet.GetClosestSurfacePointGlobal(position) - planet.WorldMatrix.Translation).Length()); }
//GetPlanetSurfaceCoordsAtPosition public static Vector3D GetPlanetSurfaceCoordsAtPosition(Vector3D coords, MyPlanet planet = null) { if (planet == null) { return(Vector3D.Zero); } var checkCoords = coords; return(planet.GetClosestSurfacePointGlobal(ref checkCoords)); }
public static Vector3D GetNearestSurfacePoint(Vector3D position, MyPlanet planet) { if (planet == null) { return(Vector3D.Zero); } var thisPosition = position; var surfacePoint = planet.GetClosestSurfacePointGlobal(ref thisPosition); return(surfacePoint); }
public static double GetDistanceFromSurface(Vector3D position, MyPlanet planet) { if (planet == null) { return(0); } var thisPosition = position; var surfacePoint = planet.GetClosestSurfacePointGlobal(ref thisPosition); return(Vector3D.Distance(thisPosition, surfacePoint)); }
public static void GetSpawnPosition(float collisionRadius, out Vector3 direction, out Vector3D position) { float distance = 0; foreach (var entity in MyEntities.GetEntities()) { // Include only voxels if (entity is MyVoxelMap) { distance = (float)MathHelper.Max(distance, entity.PositionComp.WorldVolume.Center.Length() + entity.PositionComp.WorldVolume.Radius); } } // 500 - 650m from last voxel distance += MyUtils.GetRandomFloat(500, 650); if (MyEntities.IsWorldLimited()) { distance = Math.Min(distance, MyEntities.WorldSafeHalfExtent()); } else { distance = Math.Min(distance, 20000); // limited spawn area in infinite worlds } direction = MyUtils.GetRandomVector3Normalized(); var searchPosition = MyEntities.FindFreePlace((Vector3D)(direction * distance), collisionRadius); if (!searchPosition.HasValue) { searchPosition = (Vector3D)(direction * distance); // Spawn in existing place (better than crash) } Vector3D globalPoint = (Vector3D)searchPosition; position = globalPoint; if (MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint) != null && MyGravityProviderSystem.CalculateNaturalGravityInPoint(globalPoint).Length() != 0) { MyPlanet planet = MyGravityProviderSystem.GetStrongestGravityWell(globalPoint); double multiplier = planet.MaximumRadius / globalPoint.Length(); globalPoint *= multiplier; Vector3D closestPoint = planet.GetClosestSurfacePointGlobal(ref globalPoint) * 1.25; searchPosition = MyEntities.FindFreePlace(closestPoint, collisionRadius); if (searchPosition.HasValue) { position = searchPosition.Value; } } else { position = searchPosition.Value; } }
public static Vector3D GetClosestSurface(Vector3D coords, MyPlanet planet, Water water, ref double distAboveWater, bool ignoreWater = false) { if (planet == null) { distAboveWater = 0; return(Vector3D.Zero); } if (!Enabled || water == null || ignoreWater) { distAboveWater = 0; return(planet.GetClosestSurfacePointGlobal(coords)); } else { var planetSurface = planet.GetClosestSurfacePointGlobal(coords); var waterSurface = water.GetClosestSurfacePoint(coords); var planetDist = Vector3D.Distance(planetSurface, planet.PositionComp.WorldAABB.Center); var waterDist = Vector3D.Distance(waterSurface, planet.PositionComp.WorldAABB.Center); bool dryLand = planetDist > waterDist; distAboveWater = planetDist - waterDist; return(dryLand ? planetSurface : waterSurface); } }
/// <summary> /// Gets a point outside of a planet. /// </summary> /// <param name="startPoint">Where to start the search from, can be inside or outside planet.</param> /// <param name="direction">Direction from outside of planet to inside planet.</param> /// <param name="buffer">Minimum distance between planet surface and exterior point</param> /// <param name="callback">Will be invoked on game thread with result</param> private void GetExteriorPoint_Planet(Vector3D startPoint, Vector3 direction, float buffer, Action <Vector3D> callback) { MyPlanet planet = m_targetVoxel as MyPlanet; if (planet == null) { m_logger.alwaysLog("m_targetVoxel is not MyPlanet: " + m_targetVoxel.getBestName(), Logger.severity.FATAL); throw new InvalidOperationException("m_targetVoxel is not MyPlanet"); } MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { m_surfacePoint = planet.GetClosestSurfacePointGlobal(ref startPoint); Vector3D exteriorPoint = m_surfacePoint - direction * buffer; callback(exteriorPoint); }); }
//IsPositionUnderground public static bool IsPositionUnderground(Vector3D coords, MyPlanet planet) { if (planet == null) { return(false); } var closestSurfacePoint = planet.GetClosestSurfacePointGlobal(coords); var planetEntity = planet as IMyEntity; if (Vector3D.Distance(planetEntity.GetPosition(), coords) < Vector3D.Distance(planetEntity.GetPosition(), closestSurfacePoint)) { return(true); } return(false); }
private void TestPlanet() { MyPlanet planet = m_closestPlanet; if (planet == null) { return; } IMyCubeGrid grid = m_block.CubeGrid; Vector3D myPos = grid.GetCentre(); Vector3D planetCentre = planet.GetCentre(); double distSqToPlanet = Vector3D.DistanceSquared(myPos, planetCentre); if (distSqToPlanet > planet.MaximumRadius * planet.MaximumRadius) { Log.DebugLog("higher than planet maximum"); m_planetObstruction = false; return; } Vector3D closestPoint = planet.GetClosestSurfacePointGlobal(ref myPos); if (distSqToPlanet < Vector3D.DistanceSquared(closestPoint, planetCentre)) { Log.DebugLog("below surface"); return; } float longest = grid.GetLongestDim(); if (Vector3D.DistanceSquared(myPos, closestPoint) < longest * longest) { Log.DebugLog("near surface"); m_planetObstruction = true; return; } Log.DebugLog("clear"); m_planetObstruction = false; return; }
private void TestPlanet() { MyPlanet planet = ClosestPlanet; if (planet == null) { return; } Vector3D myPos = m_grid.GetCentre(); Vector3D planetCentre = planet.GetCentre(); double distSqToPlanet = Vector3D.DistanceSquared(myPos, planetCentre); if (distSqToPlanet > planet.MaximumRadius * planet.MaximumRadius) { m_logger.debugLog("higher than planet maximum"); PlanetState = Pathfinder.PathState.No_Obstruction; return; } using (lock_closestPoint.AcquireExclusiveUsing()) m_closestPoint = planet.GetClosestSurfacePointGlobal(ref myPos); if (distSqToPlanet < Vector3D.DistanceSquared(m_closestPoint, planetCentre)) { m_logger.debugLog("below surface"); PlanetState = Pathfinder.PathState.Path_Blocked; return; } float longest = m_grid.GetLongestDim(); if (Vector3D.DistanceSquared(myPos, m_closestPoint) < longest * longest) { m_logger.debugLog("near surface"); PlanetState = Pathfinder.PathState.Path_Blocked; return; } m_logger.debugLog("clear"); PlanetState = Pathfinder.PathState.No_Obstruction; return; }
public static Vector3D VoxelHitCheck(MyVoxelBase voxel, MyPlanet closestPlanet, Vector3D lineStartPoint, Vector3D lineEndPoint, LineD lineCheck) { Vector3D?voxelHit = Vector3D.Zero; if (voxel != null) { if (voxel.RootVoxel != voxel) { return(Vector3D.Zero); } if (voxel == closestPlanet) { var closestPos = closestPlanet.GetClosestSurfacePointGlobal(ref lineStartPoint); return(closestPos); } } return(Vector3D.Zero); }
private void SpawnUndergroundDefense(IMyPlayer player) { var playerPos = player.GetPosition(); var playerNaturalGravity = marsPlanet.GetGravityAtPoint(playerPos); var vng = playerNaturalGravity; vng.Normalize(); var surface = marsPlanet.GetClosestSurfacePointGlobal(player.GetPosition()); var belowsurface = Vector3D.Distance(playerPos, surface); // ModLog.Info("Below Surface=" + belowsurface.ToString("0.00")); var up = 50 + belowsurface; // 150m above the surface // var up = 150 + belowsurface; // 150m above the surface var locationToSpawn = playerPos + vng * -up; var naturalGravityAtSpawn = marsPlanet.GetGravityAtPoint(locationToSpawn); // DuckUtils.AddGpsToAllPlayers("Location to Spawn", "Above player", locationToSpawn); var spawnLocation = MyAPIGateway.Entities.FindFreePlace(locationToSpawn, 10, 20, 5, 10); if (spawnLocation.HasValue) { PrefabGrid bomb = PrefabGrid.GetBomb(); DuckUtils.SpawnInGravity(spawnLocation.Value, naturalGravityAtSpawn, RemoteControl.OwnerId, bomb.PrefabName, bomb.InitialBeaconName); //DEBUG // DuckUtils.AddGpsToAllPlayers("Bomb Spawn", "bomb for player", spawnLocation.Value); // ModLog.Info("Spawning Bomb!"); } else { ModLog.DebugError("Couldn't spawn bomb!", locationToSpawn); } }
private void ProcessDamage() { foreach (IMyEntity entity in _topEntityCache) { var grid = entity as IMyCubeGrid; if (grid?.Physics != null) { if (grid.Closed || grid.MarkedForClose) { continue; } float damage = grid.GridSizeEnum == MyCubeSize.Small ? Config.SMALL_SHIP_DAMAGE : Config.LARGE_SHIP_DAMAGE; if (Config.BLOCK_VOXEL_DAMAGE) { byte voxelId; List <IMySlimBlock> vBlocks = Utilities.GetBlocksContactingVoxel(grid, _planet, out voxelId); VoxelDamageItem item; if (!Config.VOXEL_IDS.TryGetValue(voxelId, out item)) { MyLog.Default.WriteLine($"{voxelId} NOT FOUND"); item = Config.VOXEL_IDS.First().Value; } foreach (IMySlimBlock b in vBlocks) { _damageEntities.AddOrUpdate(b, damage * item.DamageMultiplier); if (item.ParticleEffect.HasValue) { _blockParticles[b] = item.ParticleEffect.Value; } } } if (!Config.BLOCK_RADIATION_DAMAGE && !Config.BLOCK_ACID_RAIN && Utilities.IsEntityInsideGrid(grid)) { continue; } //if (BLOCK_ACID_RAIN && IsEntityCovered(grid, sphere.Center)) //{ // //MyAPIGateway.Utilities.ShowMessage("GRID COVERED", grid.DisplayName); // continue; //} var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); Vector3D offset = Vector3D.Zero; if (Config.BLOCK_ACID_RAIN) { Vector3D direction = grid.WorldVolume.Center - _sphere.Center; direction.Normalize(); offset = direction; } if (Config.BLOCK_ACID_RAIN || Config.BLOCK_RADIATION_DAMAGE) { for (var i = 0; i < Math.Max(1, blocks.Count * 0.3); i++) { IMySlimBlock block; if (Config.BLOCK_ACID_RAIN) { block = Utilities.GetRandomSkyFacingBlock(grid, blocks, offset, true); } else { block = Utilities.GetRandomExteriorBlock(grid, blocks); } if (block == null) { continue; } _damageEntities.AddOrUpdate(block, damage); //blocks.Remove(block); //QueueInvoke(() => // { // if (block != null && !block.Closed()) // block.DoDamage(damage, _damageHash, true); // }); } } continue; } var floating = entity as IMyFloatingObject; if (floating != null) { if (floating.Closed || floating.MarkedForClose) { continue; } if (Config.BLOCK_RADIATION_DAMAGE) { _damageEntities.AddOrUpdate(floating, Config.SMALL_SHIP_DAMAGE); } if (Config.BLOCK_ACID_RAIN && !(Utilities.IsEntityCovered(floating, _sphere.Center) || Utilities.IsFullyInsideVoxel(floating, _planet))) { _damageEntities.AddOrUpdate(floating, Config.SMALL_SHIP_DAMAGE); } Vector3D pos = floating.GetPosition(); Vector3D s = _planet.GetClosestSurfacePointGlobal(ref pos); if (Vector3D.DistanceSquared(pos, s) <= 4) { MyVoxelMaterialDefinition mat = _planet.GetMaterialAt_R(ref s); VoxelDamageItem vox; if (Config.VOXEL_IDS.TryGetValue(mat.Index, out vox)) { _damageEntities.AddOrUpdate(floating, Config.LARGE_SHIP_DAMAGE * vox.DamageMultiplier); } } } } if (Config.BLOCK_ACID_RAIN && Config.DRAW_RAIN) { SendDrawQueue(); } }
public static bool SpawnWeather(MyWeatherEffectDefinition weather, Vector3D position, float radius) { MyPlanet closestPlanet = MyGamePruningStructure.GetClosestPlanet(position); if (closestPlanet == null) { return(false); } var sessionWeather = MySession.Static.GetComponent <MySectorWeatherComponent>(); var sessionWeatherPlanetData = _planetWeatherGet(sessionWeather); if (Math.Abs((double)radius) < 1) { radius = 0.1122755f * closestPlanet.AtmosphereRadius; } var weatherPosition = new Vector3D?(closestPlanet.GetClosestSurfacePointGlobal(ref position)); MyObjectBuilder_WeatherEffect builderWeatherEffect1 = new MyObjectBuilder_WeatherEffect() { Weather = weather.Id.SubtypeName, Position = weatherPosition.Value, Radius = radius }; List <MyObjectBuilder_WeatherEffect> builderWeatherEffectList = new List <MyObjectBuilder_WeatherEffect>(); BoundingSphereD boundingSphereD = new BoundingSphereD(weatherPosition.Value, (double)radius); for (int index1 = 0; index1 < sessionWeatherPlanetData.Count; ++index1) { if (sessionWeatherPlanetData[index1].PlanetId == closestPlanet.EntityId) { builderWeatherEffectList.Clear(); for (int index2 = 0; index2 < sessionWeatherPlanetData[index1].Weathers.Count; ++index2) { BoundingSphereD sphere = new BoundingSphereD(sessionWeatherPlanetData[index1].Weathers[index2].Position, (double)sessionWeatherPlanetData[index1].Weathers[index2].Radius); if (boundingSphereD.Intersects(sphere)) { builderWeatherEffectList.Add(sessionWeatherPlanetData[index1].Weathers[index2]); } } foreach (MyObjectBuilder_WeatherEffect builderWeatherEffect in builderWeatherEffectList) { sessionWeatherPlanetData[index1].Weathers.Remove(builderWeatherEffect); } } } bool flag = false; for (int index = 0; index < sessionWeatherPlanetData.Count; ++index) { if (sessionWeatherPlanetData[index].PlanetId == closestPlanet.EntityId) { sessionWeatherPlanetData[index].Weathers.Add(builderWeatherEffect1); flag = true; break; } } if (!flag) { var weatherPlanetData = new MyObjectBuilder_WeatherPlanetData() { PlanetId = closestPlanet.EntityId }; weatherPlanetData.Weathers.Add(builderWeatherEffect1); sessionWeatherPlanetData.Add(weatherPlanetData); } SyncWeather(); return(true); }
public EnvironmentEvaluation(Vector3D coords) : base() { //Non Planet Checks DistanceFromWorldCenter = Vector3D.Distance(Vector3D.Zero, coords); DirectionFromWorldCenter = Vector3D.Normalize(coords); InsideTerritories = new List <string>(); InsideStrictTerritories = new List <string>(); //Planet Checks NearestPlanet = SpawnResources.GetNearestPlanet(coords, true); if (NearestPlanet == null || !MyAPIGateway.Entities.Exist(NearestPlanet)) { return; } AltitudeAtPosition = Vector3D.Distance(NearestPlanet.GetClosestSurfacePointGlobal(coords), coords); NearestPlanetName = NearestPlanet.Generator.Id.SubtypeName; PlanetDiameter = NearestPlanet.AverageRadius * 2; var planetEntity = NearestPlanet as IMyEntity; var gravityProvider = planetEntity.Components.Get <MyGravityProviderComponent>(); if (gravityProvider != null) { if (gravityProvider.IsPositionInRange(coords) == true) { IsOnPlanet = true; } } if (!IsOnPlanet) { return; } //On Planet Checks GravityAtPosition = gravityProvider.GetGravityMultiplier(coords); AtmosphereAtPosition = NearestPlanet.GetAirDensity(coords); OxygenAtPosition = NearestPlanet.GetOxygenForPosition(coords); IsNight = MyVisualScriptLogicProvider.IsOnDarkSide(NearestPlanet, coords); WeatherAtPosition = MyVisualScriptLogicProvider.GetWeather(coords) ?? ""; //Terrain Material Checks var upDir = Vector3D.Normalize(coords - NearestPlanet.PositionComp.WorldAABB.Center); var downDir = upDir * -1; var forward = Vector3D.CalculatePerpendicularVector(upDir); var matrix = MatrixD.CreateWorld(coords, forward, upDir); var directionList = new List <Vector3D>(); directionList.Add(matrix.Forward); directionList.Add(matrix.Backward); directionList.Add(matrix.Left); directionList.Add(matrix.Right); var terrainTypes = new Dictionary <string, int>(); for (int i = 1; i < 12; i++) { foreach (var direction in directionList) { try { var checkCoordsRough = direction * (i * 15) + coords; var checkSurfaceCoords = NearestPlanet.GetClosestSurfacePointGlobal(checkCoordsRough); var checkMaterial = NearestPlanet.GetMaterialAt(ref checkSurfaceCoords); if (checkMaterial == null) { continue; } if (terrainTypes.ContainsKey(checkMaterial.MaterialTypeName)) { terrainTypes[checkMaterial.MaterialTypeName]++; } else { terrainTypes.Add(checkMaterial.MaterialTypeName, 1); } } catch (Exception e) { Logger.AddMsg("Caught Exception Trying To Determine Terrain Material", true); Logger.AddMsg(e.ToString(), true); } } } string highestCountName = ""; int highestCountNumber = 0; foreach (var material in terrainTypes.Keys) { if (string.IsNullOrWhiteSpace(highestCountName) || terrainTypes[material] > highestCountNumber) { highestCountName = material; highestCountNumber = terrainTypes[material]; } } if (!string.IsNullOrWhiteSpace(highestCountName)) { CommonTerrainAtPosition = highestCountName; } }
/// <summary> /// Determines if a given entity is on a free line of sight. /// </summary> public bool IsInView(IMyEntity Target, out Vector3D?HitPosition) { HitPosition = null; try { float RayPower = Radar.ActiveRadar ? Radar.PowerModule.EffectiveRadarPower : 800; if (Radar.MyRadarGrid == null || Radar.MyRadarGrid.Grid == null) { RadarCore.LogError("IsInView", new Exception("Radar's RadarableGrid is null!"), IsExcessive: true); return(false); } LineD LineRay = new LineD(Radar.Position, Target.GetPosition()); if (LineRay.Length <= RadarCore.GuaranteedDetectionRange) { return(true); } List <MyLineSegmentOverlapResult <MyEntity> > Overlaps = new List <MyLineSegmentOverlapResult <MyEntity> >(); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref LineRay, Overlaps); if (Overlaps == null || Overlaps.Count == 0) { return(false); } var TargetTop = Target.GetTopMostParent(); if (TargetTop == null) { RadarCore.LogError("IsInView", new Exception("Target's topmost parent is null!")); return(false); } var RadarTop = Radar.MyRadarGrid.Grid.GetTopMostParent(); if (TargetTop == null) { RadarCore.LogError("IsInView", new Exception("Radar's topmost parent is null!")); return(false); } foreach (var Overlap in Overlaps) { try { if (Overlap.Element == null || Overlap.Element.Physics == null) { continue; } LineD Intersect; var Entity = Overlap.Element as IMyEntity; if (!Entity.WorldAABB.Valid) { RadarCore.DebugWrite("IsInView.Iterate", "Found an entity with invalid WorldAABB. Skipping.", IsExcessive: true); continue; } if (Entity is IMyCubeGrid) { Entity.WorldAABB.Intersect(ref LineRay, out Intersect); } else { Entity.WorldVolume.Intersect(ref LineRay, out Intersect); } var OverlapTop = Entity.GetTopMostParent(); if (OverlapTop == null) { RadarCore.DebugWrite("IsInView.Iterate", "Found an entity with invalid topmost parent. Skipping.", IsExcessive: true); continue; } if (OverlapTop is MyPlanet) { MyPlanet Planet = OverlapTop as MyPlanet; if (Planet.HasAtmosphere) { BoundingSphereD Atmosphere = new BoundingSphereD(Planet.PositionComp.GetPosition(), Planet.AtmosphereRadius); LineD AtmoIntersect; Atmosphere.Intersect(ref LineRay, out AtmoIntersect); float Diminish = (float)(AtmoIntersect.Length * RadarCore.AtmoRayDiminishingCoefficient); RayPower -= Diminish; if (RayPower <= 0) { return(false); } } Vector3D TargetPos = Target.GetPosition(); if (Vector3D.DistanceSquared(Planet.GetClosestSurfacePointGlobal(ref TargetPos), TargetPos) < 1000 * 1000) { return(false); } } else if (OverlapTop == TargetTop) { HitPosition = Intersect.From; return(true); } else if (OverlapTop == RadarTop) { if (OverlapTop.GetPosition().DistanceTo(Radar.Position) > 1000) { List <Vector3I> GridHits = new List <Vector3I>(); Radar.MyRadarGrid.Grid.RayCastCells(Radar.Position, LineRay.To, GridHits); if (GridHits == null || GridHits.Count == 0) { continue; } if (GridHits.Contains(Radar.GridPosition)) { GridHits.Remove(Radar.GridPosition); } float Diminish = GridHits.Count * (Radar.MyRadarGrid.Grid.GridSizeEnum == MyCubeSize.Large ? 2.5f : 0.5f) * RadarCore.RayDiminishingCoefficient; RayPower -= Diminish; if (RayPower <= 0) { return(false); } } } else { float Diminish = (float)(Intersect.Length * RadarCore.RayDiminishingCoefficient); RayPower -= Diminish; if (RayPower <= 0) { return(false); } } } catch (Exception Scrap) { RadarCore.LogError("IsInView.Iterate", Scrap, IsExcessive: true); } } } catch (Exception Scrap) { RadarCore.LogError("IsInView", Scrap); } return(false); }
public static Vector3D GetClosestSurfacePointGlobal(this MyPlanet planet, Vector3D pos) { return(planet.GetClosestSurfacePointGlobal(ref pos)); }
public static List <IMySlimBlock> GetBlocksContactingVoxel(IMyCubeGrid grid, MyPlanet planet, out byte voxelType) { Vector3D[] corners = grid.WorldAABB.GetCorners(); if (corners.All(c => Vector3D.DistanceSquared(c, planet.GetClosestSurfacePointGlobal(c)) > 2500)) { voxelType = 0; return(new List <IMySlimBlock>()); } Vector3D planetPos = planet.PositionComp.GetPosition(); var result = new MyConcurrentHashSet <IMySlimBlock>(); var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks); byte id = 0; MyAPIGateway.Parallel.ForEach(blocks, block => { try { var b = block.GetPosition(); Vector3D closestSurfacePoint = planet.GetClosestSurfacePointGlobal(ref b); if (Vector3D.DistanceSquared(planetPos, closestSurfacePoint) > Vector3D.DistanceSquared(planetPos, b)) { var hits = new List <IHitInfo>(); MyAPIGateway.Physics.CastRay(b, closestSurfacePoint, hits); foreach (IHitInfo hit in hits) { if (hit.HitEntity is IMyVoxelBase) { closestSurfacePoint = hit.Position; } } } double cd = Vector3D.DistanceSquared(b, closestSurfacePoint); if (cd > 200) { return; } if (cd > 6.25) { BoundingBoxD box; block.GetWorldBoundingBox(out box, true); Vector3D[] bc = box.GetCorners(); if (bc.All(c => Vector3D.DistanceSquared(c, planet.GetClosestSurfacePointGlobal(c)) > 6.25)) { return; } } MyVoxelMaterialDefinition mat = planet.GetMaterialAt_R(ref closestSurfacePoint); if (Config.VOXEL_IDS.ContainsKey(mat.Index)) { result.Add(block); } id = mat.Index; } catch { //meh! } }); voxelType = id; return(result.ToList()); /* * var chunks = new HashSet<Vector3I[]>(); * * int chunkSize = grid.GridSizeEnum == MyCubeSize.Large ? 3 : 5; * for (int x = grid.Min.X; x < grid.Max.X + chunkSize; x += chunkSize) * { * for (int y = grid.Min.Y; y < grid.Max.Y + chunkSize; y += chunkSize) * { * for (int z = grid.Min.Z; z < grid.Max.Z + chunkSize; z += chunkSize) * { * chunks.Add(new[] * { * new Vector3I(x, y, z), * new Vector3I(x + chunkSize, y, z), * new Vector3I(x, y + chunkSize, z), * new Vector3I(x, y, z + chunkSize), * new Vector3I(x + chunkSize, y + chunkSize, z), * new Vector3I(x + chunkSize, y, z + chunkSize), * new Vector3I(x, y + chunkSize, z + chunkSize), * new Vector3I(x + chunkSize, y + chunkSize, z + chunkSize), * }); * } * } * } * * MyAPIGateway.Parallel.ForEach(chunks, chunk => * { * var success = false; * foreach (Vector3I pos in chunk) * { * Vector3D d = grid.GridIntegerToWorld(pos); * Vector3D s = planet.GetClosestSurfacePointGlobal(ref d); * if (Vector3D.DistanceSquared(d, s) > 6.25) * continue; * * if (!Config.VOXEL_IDS.ContainsKey(planet.GetMaterialAt_R(ref s).Index)) * continue; * success = true; * break; * } * * if (!success) * return; * * foreach (Vector3I pos in chunk) * { * IMySlimBlock block = grid.GetCubeBlock(pos); * if (block != null) * result.Add(block); * } * }); * * return result.ToList(); */ }
public static bool GetSpiderSpawnPosition(out MatrixD spawnPosition, Vector3D?oldPosition) { spawnPosition = MatrixD.Identity; Vector3D?position = null; MyPlanet planet = null; foreach (var player in Sync.Players.GetOnlinePlayers()) { if (player.Id.SerialId != 0) { continue; } if (player.Character == null) { continue; } position = player.GetPosition(); planet = MyGravityProviderSystem.GetNearestPlanet(position.Value); var animalSpawnInfo = GetDayOrNightAnimalSpawnInfo(planet, position.Value); if (animalSpawnInfo == null || animalSpawnInfo.Animals == null || !animalSpawnInfo.Animals.Any(x => x.AnimalType.Contains("Spider"))) { position = null; planet = null; continue; } if (oldPosition != null) // prevent teleporting from planet to planet { var planetOld = MyGravityProviderSystem.GetNearestPlanet(oldPosition.Value); if (planet != planetOld) { position = null; planet = null; continue; } } break; } if (!position.HasValue || planet == null) { return(false); } Vector3D gravity = planet.GetWorldGravity(position.Value); if (Vector3D.IsZero(gravity)) { gravity = Vector3D.Down; } else { gravity.Normalize(); } Vector3D tangent, bitangent; gravity.CalculatePerpendicularVector(out tangent); bitangent = Vector3D.Cross(gravity, tangent); Vector3D start = position.Value; start = MyUtils.GetRandomDiscPosition(ref start, 20.0f, ref tangent, ref bitangent); start -= gravity * 500; Vector3D translation = planet.GetClosestSurfacePointGlobal(ref start); Vector3D dirToPlayer = position.Value - translation; if (!Vector3D.IsZero(dirToPlayer)) { dirToPlayer.Normalize(); } else { dirToPlayer = Vector3D.CalculatePerpendicularVector(gravity); } spawnPosition = MatrixD.CreateWorld(translation, dirToPlayer, -gravity); return(true); }