protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);
            var ob = builder as MyObjectBuilder_PlanetGeneratorDefinition;

            if (ob.InheritFrom != null && ob.InheritFrom.Length > 0)
            {
                InheritFrom(ob.InheritFrom);
            }

            if (ob.PlanetMaps.HasValue)
                PlanetMaps = ob.PlanetMaps.Value;

            if (ob.HasAtmosphere.HasValue) HasAtmosphere = ob.HasAtmosphere.Value;

			if(ob.CloudLayers != null)
				CloudLayers = ob.CloudLayers;

            if (ob.SoundRules != null)
            {
                SoundRules = new MyPlanetEnvironmentalSoundRule[ob.SoundRules.Length];

                for (int ruleIndex = 0; ruleIndex < ob.SoundRules.Length; ++ruleIndex)
                {
                    MyPlanetEnvironmentalSoundRule sr;

                    sr = new MyPlanetEnvironmentalSoundRule()
                    {
                        Latitude = ob.SoundRules[ruleIndex].Latitude,
                        Height = ob.SoundRules[ruleIndex].Height,
                        SunAngleFromZenith = ob.SoundRules[ruleIndex].SunAngleFromZenith,
                        EnvironmentSound = MyStringHash.GetOrCompute(ob.SoundRules[ruleIndex].EnvironmentSound)
                    };

                    sr.Latitude.ConvertToSine();
                    sr.SunAngleFromZenith.ConvertToCosine();
                    SoundRules[ruleIndex] = sr;
                }
            }
            if (ob.MusicCategories != null)
                MusicCategories = ob.MusicCategories;

            if (ob.HillParams.HasValue)
                HillParams = ob.HillParams.Value;

            if (ob.Atmosphere != null)
                Atmosphere = ob.Atmosphere;

            if (ob.GravityFalloffPower.HasValue) GravityFalloffPower = ob.GravityFalloffPower.Value;

            if (ob.HostileAtmosphereColorShift != null)
                HostileAtmosphereColorShift = ob.HostileAtmosphereColorShift;

            if (ob.MaterialsMaxDepth.HasValue)
                MaterialsMaxDepth = ob.MaterialsMaxDepth.Value;
            if (ob.MaterialsMinDepth.HasValue)
                MaterialsMinDepth = ob.MaterialsMinDepth.Value;

            if (ob.CustomMaterialTable != null && ob.CustomMaterialTable.Length > 0)
            {
                SurfaceMaterialTable = new MyPlanetMaterialDefinition[ob.CustomMaterialTable.Length];
                for (int i = 0; i < SurfaceMaterialTable.Length; i++)
                {
                    SurfaceMaterialTable[i] = ob.CustomMaterialTable[i].Clone() as MyPlanetMaterialDefinition;
                    if (SurfaceMaterialTable[i].Material == null && !SurfaceMaterialTable[i].HasLayers)
                    {
                        MyLog.Default.WriteLine("Custom material does not contain any material ids.");
                    }
                    else if (SurfaceMaterialTable[i].HasLayers)
                    {
                        // Make the depth cumulative so we don't have to calculate it later.
                        // If we want we can even binary search it.
                        float depth = SurfaceMaterialTable[i].Layers[0].Depth;
                        for (int j = 1; j < SurfaceMaterialTable[i].Layers.Length; j++)
                        {
                            SurfaceMaterialTable[i].Layers[j].Depth += depth;
                            depth = SurfaceMaterialTable[i].Layers[j].Depth;
                        }
                    }
                }
            }

            if (ob.DistortionTable != null && ob.DistortionTable.Length > 0)
            {
                DistortionTable = ob.DistortionTable;
            }

            if (ob.DefaultSurfaceMaterial != null)
                DefaultSurfaceMaterial = ob.DefaultSurfaceMaterial;

            if (ob.DefaultSubSurfaceMaterial != null)
                DefaultSubSurfaceMaterial = ob.DefaultSubSurfaceMaterial;

            if (ob.SurfaceGravity.HasValue) SurfaceGravity = ob.SurfaceGravity.Value;

            if (ob.AtmosphereSettings != null)
                AtmosphereSettings = ob.AtmosphereSettings;

            // Folder name is not inherited to avoid weirdness.
            FolderName = ob.FolderName != null ? ob.FolderName : ob.Id.SubtypeName;

            if (ob.ComplexMaterials != null && ob.ComplexMaterials.Length > 0)
            {
                MaterialGroups = new MyPlanetMaterialGroup[ob.ComplexMaterials.Length];

                for (int k = 0; k < ob.ComplexMaterials.Length; k++)
                {
                    MaterialGroups[k] = ob.ComplexMaterials[k].Clone() as MyPlanetMaterialGroup;

                    var group = MaterialGroups[k];
                    var matRules = group.MaterialRules;
                    List<int> badMaterials = new List<int>();

                    for (int i = 0; i < matRules.Length; i++)
                    {
                        if (matRules[i].Material == null && (matRules[i].Layers == null || matRules[i].Layers.Length == 0))
                        {
                            MyLog.Default.WriteLine("Material rule does not contain any material ids.");
                            badMaterials.Add(i);
                            continue;
                        }
                        else if (matRules[i].Layers != null && matRules[i].Layers.Length != 0)
                        {
                            // Make the depth cumulative so we don't have to calculate it later.
                            // If we want we can even binary search it.
                            float depth = matRules[i].Layers[0].Depth;
                            for (int j = 1; j < matRules[i].Layers.Length; j++)
                            {
                                matRules[i].Layers[j].Depth += depth;
                                depth = matRules[i].Layers[j].Depth;
                            }
                        }

                        // We use the cosine later so we precompute it here.
                        matRules[i].Slope.ConvertToCosine();
                        matRules[i].Latitude.ConvertToSine();
                        matRules[i].Longitude.ConvertToCosineLongitude();
                    }

                    if (badMaterials.Count > 0)
                    {
                        matRules = matRules.RemoveIndices(badMaterials);
                    }

                    group.MaterialRules = matRules;
                }
            }

            if (ob.EnvironmentItems != null && ob.EnvironmentItems.Length > 0)
            {
                MaterialEnvironmentMappings = new Dictionary<int,Dictionary<string,List<MyPlanetEnvironmentMapping>>>();

                for (int i = 0; i < ob.EnvironmentItems.Length; i++)
                {
                    PlanetEnvironmentItemMapping map = ob.EnvironmentItems[i];
                    if (map.Rule != null)
                        map.Rule = map.Rule.Clone() as MyPlanetSurfaceRule;
                    else
                        map.Rule = new MyPlanetSurfaceRule();
                    map.Rule.Slope.ConvertToCosine();
                    map.Rule.Latitude.ConvertToSine();
                    map.Rule.Longitude.ConvertToCosineLongitude();
                    
                    // If the mapping does not assign a material it is ignored
                    if (map.Materials == null) break;

                    if (map.Biomes == null) map.Biomes = m_arrayOfZero;

                    foreach (var biome in map.Biomes)
                    {
                        Dictionary<string,List<MyPlanetEnvironmentMapping>> matmap;

                        if (MaterialEnvironmentMappings.ContainsKey(biome))
                        {
                            matmap = MaterialEnvironmentMappings[biome];
                        }
                        else
                        {
                            matmap = new Dictionary<string, List<MyPlanetEnvironmentMapping>>();
                            MaterialEnvironmentMappings.Add(biome, matmap);
                        }

                        foreach (var material in map.Materials)
                        {
                            if (!matmap.ContainsKey(material))
                                matmap.Add(material, new List<MyPlanetEnvironmentMapping>());

                            matmap[material].Add(new MyPlanetEnvironmentMapping(map));
                        }
                    }
                }
            }

            if (ob.OreMappings != null)
            {
                OreMappings = ob.OreMappings;
            }

            if (ob.MaterialBlending.HasValue)
            {
                MaterialBlending = ob.MaterialBlending.Value;
            }

            if (ob.SurfaceDetail != null)
            {
                Detail = ob.SurfaceDetail;
            }

            if (ob.AnimalSpawnInfo != null)
            {
                AnimalSpawnInfo = ob.AnimalSpawnInfo;
            }

            if (ob.NightAnimalSpawnInfo != null)
            {
                NightAnimalSpawnInfo = ob.NightAnimalSpawnInfo;
            }

            if (ob.SectorDensity.HasValue)
            {
                SectorDensity = ob.SectorDensity.Value;
            }
        }
 public SpawnTimeoutInfo(Vector3D position, int currentTime)
 {
     TimeoutTime = currentTime;
     Position = position;
     var planet = MyGamePruningStructure.GetClosestPlanet(Position);
     Debug.Assert(planet != null);
     AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position);
     if (AnimalSpawnInfo == null)
     {
         TimeoutTime = currentTime;
     }
 }
        private void InheritFrom(string generator)
        {
            MyPlanetGeneratorDefinition parent = MyDefinitionManager.Static.GetDefinition<MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(generator));

            if (parent == null)
            {
                MyDefinitionManager.Static.LoadingSet.m_planetGeneratorDefinitions.TryGetValue(new MyDefinitionId(typeof(MyObjectBuilder_PlanetGeneratorDefinition), generator), out parent);
            }

            if (parent == null)
            {
                MyLog.Default.WriteLine(String.Format("Could not find planet generator definition for '{0}'.", generator));
                return;
            }

            PlanetMaps = parent.PlanetMaps;
            HasAtmosphere = parent.HasAtmosphere;
            Atmosphere = parent.Atmosphere;
			CloudLayers = parent.CloudLayers;
            SoundRules = parent.SoundRules;
            MusicCategories = parent.MusicCategories;
            HillParams = parent.HillParams;
            MaterialsMaxDepth = parent.MaterialsMaxDepth;
            MaterialsMinDepth = parent.MaterialsMinDepth;
            GravityFalloffPower = parent.GravityFalloffPower;
            HostileAtmosphereColorShift = parent.HostileAtmosphereColorShift;
            SurfaceMaterialTable = parent.SurfaceMaterialTable;
            DistortionTable = parent.DistortionTable;
            DefaultSurfaceMaterial = parent.DefaultSurfaceMaterial;
            DefaultSubSurfaceMaterial = parent.DefaultSubSurfaceMaterial;
            MaterialGroups = parent.MaterialGroups;
            MaterialEnvironmentMappings = parent.MaterialEnvironmentMappings;
            SurfaceGravity = parent.SurfaceGravity;
            AtmosphereSettings = parent.AtmosphereSettings;
            FolderName = parent.FolderName;
            MaterialBlending = parent.MaterialBlending;
            OreMappings = parent.OreMappings;
            AnimalSpawnInfo = parent.AnimalSpawnInfo;
            NightAnimalSpawnInfo = parent.NightAnimalSpawnInfo;
            Detail = parent.Detail;
            SectorDensity = parent.SectorDensity;
        }
        private MyBotDefinition GetAnimalDefinition(MyPlanetAnimalSpawnInfo animalSpawnInfo)
        {
            Debug.Assert(animalSpawnInfo != null, "Missing animal spawn info in planet definition.");
            Debug.Assert(animalSpawnInfo.Animals != null, "Missing array of animals in planet definition.");
            Debug.Assert(animalSpawnInfo.Animals.Length > 0, "Array of animals is empty in planet definition.");

            int animalIndex = MyUtils.GetRandomInt(0, animalSpawnInfo.Animals.Length);
            var animalDefinition = new MyDefinitionId(typeof(VRage.Game.ObjectBuilders.AI.Bot.MyObjectBuilder_AnimalBot), animalSpawnInfo.Animals[animalIndex].AnimalType);
            return MyDefinitionManager.Static.GetBotDefinition(animalDefinition) as MyAgentDefinition;
        }
        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);
                }
            }
        }
 public SpawnTimeoutInfo(MyObjectBuilder_SpaceFaunaComponent.TimeoutInfo info, int currentTime)
 {
     TimeoutTime = currentTime + info.Timeout;
     Position = new Vector3D(info.X, info.Y, info.Z);
     var planet = MyGamePruningStructure.GetClosestPlanet(Position);
     AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position);
     if (AnimalSpawnInfo == null)
     {
         TimeoutTime = currentTime;
     }
 }
 public SpawnTimeoutInfo(Vector3D position, int currentTime)
 {
     TimeoutTime = currentTime;
     Position = position;
     var planet = MyGravityProviderSystem.GetNearestPlanet(Position);
     Debug.Assert(planet != null);
     AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position);
     if (AnimalSpawnInfo == null)
     {
         TimeoutTime = currentTime;
     }
 }
 public SpawnTimeoutInfo(MyObjectBuilder_SpaceFaunaComponent.TimeoutInfo info, int currentTime)
 {
     TimeoutTime = currentTime + info.Timeout;
     Position = new Vector3D(info.X, info.Y, info.Z);
     var planet = MyGravityProviderSystem.GetNearestPlanet(Position);
     AnimalSpawnInfo = MySpaceBotFactory.GetDayOrNightAnimalSpawnInfo(planet, Position);
     if (AnimalSpawnInfo == null)
     {
         TimeoutTime = currentTime;
     }
 }