public override void CloseObject(MyObjectSeed obj)
        {
            List <MyVoxelBase> voxelMaps = new List <MyVoxelBase>();
            var bounds = obj.BoundingVolume;

            MyGamePruningStructure.GetAllVoxelMapsInBox(ref bounds, voxelMaps);

            string storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", obj.CellId.X, obj.CellId.Y, obj.CellId.Z, obj.Params.Index, obj.Params.Seed);

            foreach (MyVoxelBase map in voxelMaps)
            {
                if (map.StorageName == storageName)
                {
                    if (m_NotSavedMaps.Contains(map))
                    {
                        Action <MyEntity> onClose = null;
                        onClose = delegate
                        {
                            obj.Params.Generated = false;
                            map.OnClose         -= onClose;
                        };
                        map.Save = false;
                        map.Close();
                        map.OnClose += onClose;
                        m_NotSavedMaps.Remove(map);
                    }
                    break;
                }
            }

            voxelMaps.Clear();
        }
        public override MyProceduralCell GenerateCell(ref Vector3I id)
        {
            MyProceduralCell cell = new MyProceduralCell(id, CELL_SIZE_);
            int cellSeed          = GetCellSeed(ref id);

            using (MyRandom.Instance.PushSeed(cellSeed))
            {
                int index = 0;

                int subCellSize = (int)(OBJECT_SIZE_MAX * 2 / m_density);
                int subcells    = CELL_SIZE_ / subCellSize;

                Vector3I subcellId = Vector3I.Zero;
                Vector3I max       = new Vector3I(subcells - 1);

                for (var it = new Vector3I_RangeIterator(ref Vector3I.Zero, ref max); it.IsValid(); it.GetNext(out subcellId))
                {
                    Vector3D position = new Vector3D(MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble());
                    position += (Vector3D)subcellId;
                    position *= subCellSize;
                    position += id * CELL_SIZE_;

                    if (!MyEntities.IsInsideWorld(position))
                    {
                        continue;
                    }

                    MySystemItem obj = IsInsideRing(position);

                    if (obj == null)
                    {
                        continue;
                    }
                    int minSize = OBJECT_SIZE_MIN;
                    int maxSize = OBJECT_SIZE_MAX;

                    if (obj.Type == SystemObjectType.BELT)
                    {
                        minSize = ((MySystemBeltItem)obj).RoidSize;
                    }

                    if (obj.Type == SystemObjectType.RING)
                    {
                        minSize = ((MyPlanetRingItem)obj).RoidSize;
                        maxSize = ((MyPlanetRingItem)obj).RoidSizeMax;
                    }

                    var cellObject = new MyObjectSeed(cell, position, MyRandom.Instance.Next(Math.Min(maxSize, minSize), Math.Max(maxSize, minSize)));
                    cellObject.Params.Type  = MyObjectSeedType.Asteroid;
                    cellObject.Params.Seed  = MyRandom.Instance.Next();
                    cellObject.Params.Index = index++;

                    cell.AddObject(cellObject);
                }
            }

            return(cell);
        }
        protected override MyProceduralCell GenerateCellSeeds(Vector3I cellId)
        {
            if (m_loadedCells.ContainsKey(cellId))
            {
                return(null);
            }

            var settings = MySettingsSession.Static.Settings.GeneratorSettings;

            if (settings.AsteroidGenerator == AsteroidGenerationMethod.VANILLA)
            {
                return(null);
            }

            MyProceduralCell cell = new MyProceduralCell(cellId, CELL_SIZE);
            int    cellSeed       = CalculateCellSeed(cellId);
            int    index          = 0;
            double subCellSize    = OBJECT_SIZE_MAX * 1f / settings.AsteroidDensity;
            int    subcells       = (int)(CELL_SIZE / subCellSize);

            using (MyRandom.Instance.PushSeed(cellSeed))
            {
                Vector3I subcellId = Vector3I.Zero;
                Vector3I max       = new Vector3I(subcells - 1);

                for (var it = new Vector3I_RangeIterator(ref Vector3I.Zero, ref max); it.IsValid(); it.GetNext(out subcellId))
                {
                    Vector3D position = new Vector3D(MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble());
                    position += (Vector3D)subcellId;
                    position *= subCellSize;
                    position += ((Vector3D)cellId) * CELL_SIZE;

                    if (!MyEntities.IsInsideWorld(position) || (settings.WorldSize >= 0 && position.Length() > settings.WorldSize))
                    {
                        continue;
                    }

                    var ring = GetAsteroidObjectAt(position);

                    if (ring == null)
                    {
                        continue;
                    }

                    var cellObjectSeed = new MyObjectSeed(cell, position, MyRandom.Instance.Next(ring.AsteroidSize.Min, ring.AsteroidSize.Max));
                    cellObjectSeed.Params.Type          = VRage.Game.MyObjectSeedType.Asteroid;
                    cellObjectSeed.Params.Seed          = MyRandom.Instance.Next();
                    cellObjectSeed.Params.Index         = index++;
                    cellObjectSeed.Params.GeneratorSeed = m_definition.UseGeneratorSeed ? MyRandom.Instance.Next() : 0;

                    cell.AddObject(cellObjectSeed);

                    MyPluginLog.Debug("Adding seed");
                }
            }

            return(cell);
        }
        /// <summary>
        /// Gets the seed of the object based on the objects hashcode.
        /// </summary>
        /// <param name="obj">The MyObjectSeed for the object</param>
        /// <returns>The seed of the object</returns>
        protected int GetObjectIdSeed(MyObjectSeed obj)
        {
            int hash = obj.CellId.GetHashCode();

            hash = (hash * 397) ^ m_seed;
            hash = (hash * 397) ^ obj.Params.Index;
            hash = (hash * 397) ^ obj.Params.Seed;
            return(hash);
        }
 /// <summary>
 /// Closes the specified object. This should remove it from the world and memory.
 /// </summary>
 /// <param name="seed">The MyObjectSeed of the object that should be removed.</param>
 public abstract void CloseObject(MyObjectSeed seed);
        public override void CloseObject(MyObjectSeed seed)
        {
            m_existingObjectSeeds.Remove(seed);
            MyVoxelBase voxelMap;

            if (seed.UserData != null)
            {
                if (seed.UserData is MyVoxelBase)
                {
                    voxelMap = seed.UserData as MyVoxelBase;

                    if (!m_tmpAsteroids.Contains(voxelMap))
                    {
                        return;
                    }

                    if (!m_tmpAsteroids.Remove(voxelMap))
                    {
                        for (int i = 0; i < m_tmpAsteroids.Count; i++)
                        {
                            if (m_tmpAsteroids[i].StorageName.Equals(voxelMap.StorageName))
                            {
                                m_tmpAsteroids.RemoveAt(i);
                                voxelMap.Save = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        voxelMap.Save = false;
                    }

                    voxelMap.IsSeedOpen = false;
                    seed.UserData       = null;

                    voxelMap.Close();
                }
            }
            else
            {
                List <MyVoxelBase> voxelMaps = new List <MyVoxelBase>();
                var bounds = seed.BoundingVolume;

                MyGamePruningStructure.GetAllVoxelMapsInBox(ref bounds, voxelMaps);

                string storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", seed.CellId.X, seed.CellId.Y, seed.CellId.Z, seed.Params.Index, seed.Params.Seed);

                foreach (MyVoxelBase map in voxelMaps)
                {
                    if (map.StorageName == storageName)
                    {
                        if (m_tmpAsteroids.Contains(map))
                        {
                            map.Save = false;

                            m_tmpAsteroids.Remove(map);
                            map.IsSeedOpen = false;
                            map.Close();
                            break;
                        }
                    }
                }

                voxelMaps.Clear();
            }
        }
        public override void CloseObject(MyObjectSeed seed)
        {
            m_existingObjectSeeds.Remove(seed);
            MyVoxelBase voxelMap;

            if (seed.UserData != null)
            {
                if (seed.UserData is MyVoxelBase)
                {
                    voxelMap = seed.UserData as MyVoxelBase;

                    //If the reference cant be found, search the array by comparing storage names.
                    //Only a failsafe, if somehow the voxelmap references differs, should not happen normally.
                    if (!m_tmpAsteroids.Remove(voxelMap))
                    {
                        for (int i = 0; i < m_tmpAsteroids.Count; i++)
                        {
                            if (m_tmpAsteroids[i].StorageName.Equals(voxelMap.StorageName))
                            {
                                m_tmpAsteroids.RemoveAt(i);
                                voxelMap.Save = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        voxelMap.Save = false;
                    }

                    voxelMap.IsSeedOpen = false;
                    seed.UserData       = null;

                    voxelMap.Close();
                }
            }
            else
            {
                List <MyVoxelBase> voxelMaps = new List <MyVoxelBase>();
                var bounds = seed.BoundingVolume;

                MyGamePruningStructure.GetAllVoxelMapsInBox(ref bounds, voxelMaps);

                string storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", seed.CellId.X, seed.CellId.Y, seed.CellId.Z, seed.Params.Index, seed.Params.Seed);

                foreach (MyVoxelBase map in voxelMaps)
                {
                    if (map.StorageName == storageName)
                    {
                        if (m_tmpAsteroids.Contains(map))
                        {
                            map.Save = false;
                        }

                        m_tmpAsteroids.Remove(map);
                        map.IsSeedOpen = false;
                        map.Close();
                        break;
                    }
                }

                voxelMaps.Clear();
            }
        }