/// <summary> /// Generates a random amount of moons for a planet /// </summary> /// <param name="parentPlanet"></param> /// <returns></returns> private MySystemPlanetMoon[] GeneratePlanetMoons(MySystemPlanet parentPlanet) { MyPluginLog.Log("Generating moons for planet " + parentPlanet.DisplayName); var settings = MySettingsSession.Static.Settings.GeneratorSettings; uint maxMoons = (uint)Math.Ceiling(parentPlanet.Diameter / 120000 * 2); maxMoons = (uint)Math.Min(maxMoons, settings.PlanetSettings.MinMaxMoons.Max); uint numMoons = (uint)MyRandom.Instance.Next(settings.PlanetSettings.MinMaxMoons.Min, (int)maxMoons + 1); numMoons = Math.Min(numMoons, 25); if (settings.SystemGenerator == SystemGenerationMethod.UNIQUE) { numMoons = Math.Min(numMoons, (uint)m_moons.Count); } MySystemPlanetMoon[] moons = new MySystemPlanetMoon[numMoons]; for (int i = 0; i < numMoons; i++) { MyPluginLog.Log("Generating moon " + i); double distance = parentPlanet.Diameter * (i + 1) + parentPlanet.Diameter * MyRandom.Instance.GetRandomFloat(1f, 1.5f); double diameter; var definition = FindPlanetDefinitionForSize(parentPlanet.Diameter * 0.75f, out diameter, true); if (definition == null) { return(moons); } Vector3D position; int tries2 = 0; do { double angle = MyRandom.Instance.GetRandomFloat(0, (float)Math.PI * 2f); position = new Vector3D(distance * Math.Sin(angle), distance * Math.Cos(angle), distance * Math.Sin(MyRandom.Instance.GetRandomFloat((float)-Math.PI / 2, (float)Math.PI / 2))); position = Vector3D.Add(position, parentPlanet.CenterPosition); } while (IsMoonPositionObstructed(position, diameter, parentPlanet, moons) && ++tries2 < MAX_DEF_FIND_ROUNDS); MySystemPlanetMoon moon = new MySystemPlanetMoon(); moon.CenterPosition = position; moon.Diameter = diameter; moon.DisplayName = GetMoonName(i, definition.Id.SubtypeId.String, parentPlanet.DisplayName); moon.SubtypeId = definition.Id.SubtypeId.String; moon.ParentId = parentPlanet.Id; moons[i] = moon; } MyPluginLog.Log("Generating moons for planet " + parentPlanet.DisplayName + " completed"); return(moons); }
/// <summary> /// Generates a ring for the given planet /// </summary> /// <param name="parentPlanet">Planet the ring is based on</param> /// <returns>The ring for the planet</returns> private MySystemAsteroids GenrateRing(MySystemPlanet parentPlanet) { MyPluginLog.Log("Generating ring for planet " + parentPlanet.DisplayName); var provider = MyAsteroidObjectsManager.Static.AsteroidObjectProviders[MyAsteroidRingProvider.TYPE_NAME]; var ring = provider.GenerateInstance(0, parentPlanet, 0); return(ring); }
/// <summary> /// Generates a planet for the star system. /// </summary> /// <param name="planetIndex">Index of the planet in the system</param> /// <param name="maxDiameter">The largest diameter the planet should have</param> /// <param name="orbitDistance">The distance the planet is away from Vector3D.Zero</param> /// <returns>A new MySystemPlanet</returns> private MySystemPlanet GeneratePlanet(int planetIndex, double maxDiameter, long orbitDistance) { MyPluginLog.Log("Generating new planet"); var settings = MySettingsSession.Static.Settings.GeneratorSettings.PlanetSettings; var def = FindPlanetDefinitionForSize(maxDiameter); if (def == null) { MyPluginLog.Log("Could not load a planet definition for this planet.", LogLevel.WARNING); return(null); } var diameter = CalculatePlanetDiameter(def); var angle = MyRandom.Instance.GetRandomFloat(0, (float)(2 * Math.PI)); var elevation = MyRandom.Instance.GetRandomFloat((float)Math.PI / 180 * -5, (float)Math.PI / 180 * 5); Vector3D pos = new Vector3D(orbitDistance * Math.Sin(angle), orbitDistance * Math.Cos(angle), orbitDistance * Math.Sin(elevation)); string name = GetPlanetName(planetIndex, def.Id.SubtypeId.String); MySystemPlanet planet = new MySystemPlanet() { CenterPosition = pos, Diameter = diameter, DisplayName = name, Generated = false, SubtypeId = def.Id.SubtypeId.String, }; if (MyRandom.Instance.NextFloat() < settings.BaseRingProbability * def.SurfaceGravity) { planet.ChildObjects.Add(GenrateRing(planet)); } if (MyRandom.Instance.NextFloat() < settings.BaseMoonProbability * def.SurfaceGravity) { foreach (var moon in GeneratePlanetMoons(planet)) { if (moon == null) { continue; } planet.ChildObjects.Add(moon); } } MyPluginLog.Log("Planet generated"); return(planet); }
public override void GenerateObjects() { var system = MyStarSystemGenerator.Static.StarSystem; if (system == null || system.CenterObject == null) { return; } var objs = system.GetAllObjects(); foreach (var obj in objs) { if (obj == null) { continue; } if (obj.Type != MySystemObjectType.PLANET && obj.Type != MySystemObjectType.MOON) { continue; } MySystemPlanet planet = obj as MySystemPlanet; if (planet.Generated) { continue; } var definition = MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(planet.SubtypeId)); if (definition == null) { continue; } long id = MyRandom.Instance.NextLong(); string name = GetPlanetStorageName(planet); MyPlanet generatedPlanet = MyWorldGenerator.AddPlanet(name, planet.DisplayName, planet.SubtypeId, planet.CenterPosition - GetPlanetOffset(definition, planet.Diameter), m_seed, (float)planet.Diameter, true, id, false, true); if (generatedPlanet != null) { generatedPlanet.DisplayNameText = planet.DisplayName; generatedPlanet.AsteroidName = planet.DisplayName; planet.Generated = true; planet.EntityId = generatedPlanet.EntityId; } } }
/// <summary> /// Spawns a planet in the system /// </summary> /// <param name="planet">Planet to spawn</param> /// <param name="position">Position to spawn at</param> private void SpawnPlanet(MySystemObject planet, Vector3D position) { if (planet.Type == MySystemObjectType.PLANET) { MySystemPlanet p = planet as MySystemPlanet; p.CenterPosition = position; MyStarSystemGenerator.Static.AddObjectToSystem(p, callback : delegate(bool success) { if (!success) { MyPluginGuiHelper.DisplayError("Planet could not be spawned, because an object with the same id already exists. This error should not occour, so please try again.", "Error"); } }); } }
/// <summary> /// Action to spawn a planet /// </summary> /// <param name="coordSpawn">If the planet should be spawned at coordinates instead of direct placement</param> private void OnSpawnPlanet(bool coordSpawn = false) { StringBuilder name = new StringBuilder(); m_nameBox.GetText(name); if (name.ToString().Trim().Length <= 3) { MyPluginGuiHelper.DisplayError("The name must be at least 4 letters long", "Error"); return; } if (coordSpawn) { MyGuiScreenDialogCoordinate coordinateInput = new MyGuiScreenDialogCoordinate("Planet coordinate"); coordinateInput.OnConfirmed += delegate(Vector3D coord) { MySystemPlanet p = new MySystemPlanet() { CenterPosition = coord, SubtypeId = ((MyPlanetGeneratorDefinition)m_planetDefList.GetLastSelected().UserData).Id.SubtypeId.ToString(), Generated = false, DisplayName = name.ToString().Trim(), Diameter = m_planetSizeSlider.Value }; SpawnPlanet(p, coord); }; MyGuiSandbox.AddScreen(coordinateInput); return; } float size = m_planetSizeSlider.Value; MySystemPlanet planet = new MySystemPlanet() { CenterPosition = Vector3D.Zero, SubtypeId = ((MyPlanetGeneratorDefinition)m_planetDefList.GetLastSelected().UserData).Id.SubtypeId.ToString(), Generated = false, DisplayName = name.ToString().Trim(), Diameter = size }; MyPluginItemsClipboard.Static.Activate(planet, SpawnPlanet, size); CloseScreenNow(); }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (!MySettingsSession.Static.IsEnabled()) { return; } CheckIntegrityOfSystem(); List <MyEntityList.MyEntityListInfoItem> planets = MyEntityList.GetEntityList(MyEntityList.MyEntityTypeEnum.Planets); foreach (var p in planets) { var e = MyEntities.GetEntityById(p.EntityId) as MyPlanet; bool exists = false; foreach (var obj in StarSystem.GetAllObjects()) { if (obj is MySystemPlanet) { if ((obj as MySystemPlanet).EntityId == p.EntityId) { exists = true; } } } if (!exists) { MySystemPlanet vanillaPlanet = new MySystemPlanet(); vanillaPlanet.CenterPosition = e.PositionComp.GetPosition(); vanillaPlanet.Diameter = e.MaximumRadius * 2; vanillaPlanet.DisplayName = GetPlanetNameForPlanetStorageName(e.StorageName); vanillaPlanet.Generated = true; vanillaPlanet.EntityId = p.EntityId; StarSystem.CenterObject.ChildObjects.Add(vanillaPlanet); } } AddAllPersistentGps(); }
/// <summary> /// Checks, whether a given position, where a moon with given diameter is located, is obstructed by moons or a planet or its ring. /// Helper method for GeneratePlanetMoons /// </summary> /// <param name="position">Position to check</param> /// <param name="moonDiameter">Diameter of moon</param> /// <param name="parentPlanet">Planet to check ring</param> /// <param name="moons">Moons to check</param> /// <returns></returns> private bool IsMoonPositionObstructed(Vector3D position, double moonDiameter, MySystemPlanet parentPlanet, MySystemPlanetMoon[] moons) { if (Vector3D.Distance(position, parentPlanet.CenterPosition) < moonDiameter + parentPlanet.Diameter) { return(true); } foreach (var child in parentPlanet.ChildObjects) { if (child.Type == MySystemObjectType.ASTEROIDS) { var asteroid = child as MySystemAsteroids; IMyAsteroidObjectShape shape = MyAsteroidObjectsManager.Static.AsteroidObjectProviders[asteroid.AsteroidTypeName].GetAsteroidObjectShape(asteroid); if (Vector3D.Distance(shape.GetClosestPoint(position), position) <= moonDiameter) { return(true); } } else { if (child.GetType() == typeof(MySystemPlanet)) { if (Vector3D.Distance(child.CenterPosition, position) < moonDiameter + (child as MySystemPlanet).Diameter) { return(true); } } } } foreach (var moon in moons) { if (moon == null) { continue; } if (Vector3D.Distance(moon.CenterPosition, position) < moonDiameter + moon.Diameter) { return(true); } } return(false); }
/// <summary> /// Generates a completely new system based on the /// world settings. /// </summary> /// <returns></returns> private MyObjectBuilder_SystemData GenerateNewStarSystem() { MyPluginLog.Log("Generating a new Solar system ..."); int seed = MySession.Static.Settings.ProceduralSeed + Guid.NewGuid().GetHashCode(); MyObjectBuilder_SystemData system = new MyObjectBuilder_SystemData(); var settings = MySettingsSession.Static.Settings.GeneratorSettings; var orbitDistances = settings.MinMaxOrbitDistance; var planetsAmount = settings.MinMaxPlanets; var asteroidObjectAmount = settings.MinMaxAsteroidObjects; var worldSize = settings.WorldSize; var asteroidProviders = MyAsteroidObjectsManager.Static.AsteroidObjectProviders; using (MyRandom.Instance.PushSeed(seed)) { long planetCount = MyRandom.Instance.Next(planetsAmount.Min, planetsAmount.Max + 1); long asteroidObjectCount = MyRandom.Instance.Next(asteroidObjectAmount.Min, asteroidObjectAmount.Max + 1); long systemSize = planetCount + asteroidObjectCount; int currentPlanetIndex = 0; int currentAsteroidIndex = 0; long currentOrbitDistance = 0; double planetProb = planetCount / (double)(planetCount + asteroidObjectCount); if (m_suns.Count > 0) { MyPlanetGeneratorDefinition sunDef = m_suns[MyRandom.Instance.Next(0, m_suns.Count)]; MySystemPlanet sun = new MySystemPlanet(); sun.CenterPosition = Vector3D.Zero; sun.SubtypeId = sunDef.Id.SubtypeId.String; sun.DisplayName = sunDef.Id.SubtypeId.String; sun.Diameter = CalculatePlanetDiameter(sunDef) * 2; sun.ChildObjects = new HashSet <MySystemObject>(); sun.Generated = false; sun.Type = MySystemObjectType.PLANET; system.CenterObject = sun; currentOrbitDistance += (long)sun.Diameter * 2 + (long)sunDef.AtmosphereHeight; } else { system.CenterObject = new MySystemObject(); system.CenterObject.Type = MySystemObjectType.EMPTY; system.CenterObject.DisplayName = "System center"; } while (planetCount > 0 || asteroidObjectCount > 0) { currentOrbitDistance += MyRandom.Instance.Next(orbitDistances.Min, orbitDistances.Max); //Maybe rework to override orbit distance, so all objects fit if (worldSize >= 0 && currentOrbitDistance >= worldSize) { return(system); } MySystemObject obj = null; if (asteroidObjectCount <= 0 || (MyRandom.Instance.NextDouble() <= planetProb && planetCount > 0)) // Generate planet { obj = GeneratePlanet(currentPlanetIndex++, Math.Sin((system.Count() - 1) * Math.PI / systemSize), currentOrbitDistance); planetCount--; } else if (asteroidObjectCount > 0) // Generate asteroid object { int providerIndex = MyRandom.Instance.Next(0, asteroidProviders.Keys.Count); MyAbstractAsteroidObjectProvider provider = null; foreach (var prov in asteroidProviders) { if (!prov.Value.IsSystemGeneratable()) { continue; } if (providerIndex-- == 0) { provider = prov.Value; } } if (provider == null) { continue; } obj = provider.GenerateInstance(currentAsteroidIndex++, null, currentOrbitDistance); if (obj == null) { continue; } (obj as MySystemAsteroids).AsteroidTypeName = provider.GetTypeName(); asteroidObjectCount--; } if (obj == null) { continue; } obj.ParentId = system.CenterObject.Id; system.CenterObject.ChildObjects.Add(obj); } } MyPluginLog.Log("Solar system generated ..."); return(system); }
/// <summary> /// Builds all elements to edit planets /// </summary> /// <param name="table">Table to add the elements to</param> /// <param name="planet">Planet item to build the edit menu for</param> private void BuildPlanetEditingMenu(MyGuiControlParentTableLayout table, MySystemPlanet planet) { table.AddTableRow(new MyGuiControlLabel(null, null, "This object cant be edited.", font: "Red")); }
/// <summary> /// Returns the storage name for the given planet /// </summary> /// <param name="planet">Planet to get a storage name for</param> /// <returns>The storage name of the planet</returns> private string GetPlanetStorageName(MySystemPlanet planet) { return((planet.DisplayName + "-" + planet.SubtypeId).Replace(" ", "_")); }