//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;
                    }
                }
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
        /// <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());
        }
Beispiel #8
0
        //GetPlanetSurfaceCoordsAtPosition
        public static Vector3D GetPlanetSurfaceCoordsAtPosition(Vector3D coords, MyPlanet planet = null)
        {
            if (planet == null)
            {
                return(Vector3D.Zero);
            }

            var checkCoords = coords;

            return(planet.GetClosestSurfacePointGlobal(ref checkCoords));
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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;
            }
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        /// <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);
            });
        }
Beispiel #14
0
        //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);
        }
Beispiel #15
0
        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;
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        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();
            }
        }
Beispiel #20
0
        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);
        }
Beispiel #23
0
 public static Vector3D GetClosestSurfacePointGlobal(this MyPlanet planet, Vector3D pos)
 {
     return(planet.GetClosestSurfacePointGlobal(ref pos));
 }
Beispiel #24
0
        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();
             */
        }
Beispiel #25
0
        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);
        }