public override void ResetVariables()
 {
     base.ResetVariables();
     _body                   = "";
     _bodyValue              = 0;
     _gravity                = "";
     _atmosphericPresence    = "";
     _hasAtmosphere          = false;
     _atmosphericComposition = "";
     _atmosphereTainted      = false;
     _atmospherePure         = false;
     _climate                = "";
     _habitabiliy            = Habitabiliy.Inhospitable;
     _orbitalFeaturesNode    = null;
     _nativeSpeciesNode      = null;
     _primitiveXenosNode     = null;
     _numContinents          = 0;
     _numIslands             = 0;
     _environment            = null;
     ClimateType             = ClimateTypes.Undefined;
     AtmosphereType          = AtmosphereTypes.Undefined;
     _forceInhabitable       = false;
     _isInhabitantHomeWorld  = false;
 }
        public override void Generate()
        {
            _primitiveXenosNode = new PrimitiveXenosNode(_systemCreationRules)
            {
                Parent = this
            };
            Children.Add(_primitiveXenosNode);
            _nativeSpeciesNode = new NativeSpeciesNode(_systemCreationRules)
            {
                Parent = this
            };
            Children.Add(_nativeSpeciesNode);

            NodeBase zoneNode = Parent;

            while (!(zoneNode is ZoneNode))
            {
                zoneNode = zoneNode.Parent;
            }
            _effectiveSystemZone = (zoneNode as ZoneNode).Zone;
            if (_effectiveSystemZoneCloserToSun)
            {
                switch (_effectiveSystemZone)
                {
                case SystemZone.InnerCauldron:
                    break;

                case SystemZone.PrimaryBiosphere:
                    _effectiveSystemZone = SystemZone.InnerCauldron;
                    break;

                case SystemZone.OuterReaches:
                    _effectiveSystemZone = SystemZone.PrimaryBiosphere;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            int gravityRollModifier = 0;
            EffectivePlanetSize effectivePlanetSize = EffectivePlanetSize.Small;
            int maximumMineralResourceAbundance     = -1;
            int mineralResourceAbundanceModifier    = 0;
            int orbitalFeaturesModifier             = 0;
            int atmosphericPresenceModifier         = 0;
            int atmosphericCompositionModifier      = 0;
            int habitabilityModifier = 0;
            int maxHabitabilityRoll  = 9999;

            // Generate Body
            int randValue = Globals.RollD10();

            if (randValue > _maxSize)
            {
                randValue = _maxSize;
            }
            switch (randValue)
            {
            case 1:
                _body = "Low-Mass";
                gravityRollModifier            -= 7;
                effectivePlanetSize             = EffectivePlanetSize.Small;
                maximumMineralResourceAbundance = 40;
                break;

            case 2:
            case 3:
                _body = "Small";
                gravityRollModifier -= 5;
                effectivePlanetSize  = EffectivePlanetSize.Small;
                break;

            case 4:
                _body = "Small and Dense";
                effectivePlanetSize = EffectivePlanetSize.Small;
                mineralResourceAbundanceModifier += 10;
                break;

            case 5:
            case 6:
            case 7:
                _body = "Large";
                effectivePlanetSize = EffectivePlanetSize.Large;
                break;

            case 8:
                _body = "Large and Dense";
                effectivePlanetSize  = EffectivePlanetSize.Large;
                gravityRollModifier += 5;
                mineralResourceAbundanceModifier += 10;
                break;

            case 9:
            case 10:
                _body = "Vast";
                effectivePlanetSize  = EffectivePlanetSize.Vast;
                gravityRollModifier += 4;
                break;
            }
            _bodyValue = randValue;

            int numOrbitalFeaturesToGenerate;

            // Generate Gravity
            randValue = Globals.RollD10() + gravityRollModifier;
            if (randValue <= 2)
            {
                _gravity = "Low";
                orbitalFeaturesModifier     -= 10;
                atmosphericPresenceModifier -= 2;
                numOrbitalFeaturesToGenerate = Globals.RollD5() - 3;
            }
            else if (randValue <= 8)
            {
                _gravity = "Normal";
                numOrbitalFeaturesToGenerate = Globals.RollD5() - 2;
            }
            else
            {
                _gravity = "High";
                orbitalFeaturesModifier     += 10;
                atmosphericPresenceModifier += 1;
                numOrbitalFeaturesToGenerate = Globals.RollD5() - 1;
            }

            if (numOrbitalFeaturesToGenerate < 1)
            {
                numOrbitalFeaturesToGenerate = 1;
            }
            if (_isMoon)
            {
                numOrbitalFeaturesToGenerate = 0;
            }

            // Generate Orbital Features
            for (int i = 0; i < numOrbitalFeaturesToGenerate; i++)
            {
                randValue = Globals.RollD100() + orbitalFeaturesModifier;
                if (randValue <= 45)
                {
                    // No feature
                }
                else if (randValue <= 60)
                {
                    // Generate an Asteroid
                    if (_orbitalFeaturesNode == null)
                    {
                        _orbitalFeaturesNode = new OrbitalFeaturesNode(_systemCreationRules)
                        {
                            Parent = this
                        };
                        Children.Add(_orbitalFeaturesNode);
                    }
                    _orbitalFeaturesNode.AddAsteroid();
                }
                else if (randValue <= 90)
                {
                    // Generate a Lesser Moon
                    if (_orbitalFeaturesNode == null)
                    {
                        _orbitalFeaturesNode = new OrbitalFeaturesNode(_systemCreationRules)
                        {
                            Parent = this
                        };
                        Children.Add(_orbitalFeaturesNode);
                    }
                    _orbitalFeaturesNode.AddLesserMoon();
                }
                else
                {
                    // Generate a Moon
                    if (_orbitalFeaturesNode == null)
                    {
                        _orbitalFeaturesNode = new OrbitalFeaturesNode(_systemCreationRules)
                        {
                            Parent = this
                        };
                        Children.Add(_orbitalFeaturesNode);
                    }
                    _orbitalFeaturesNode.AddMoon(_bodyValue, false);
                }
            }
            GenerateNamesForOrbitalFeatures();

            // Generate Atmospheric Presence
            if (_systemCreationRules.HavenThickerAtmospheresInPrimaryBiosphere &&
                _effectiveSystemZone == SystemZone.PrimaryBiosphere)
            {
                atmosphericPresenceModifier    += 1;
                atmosphericCompositionModifier += 2;
            }

            randValue = Globals.RollD10() + atmosphericPresenceModifier;
            if (randValue <= 1 && !_forceInhabitable)
            {
                AtmosphereType       = AtmosphereTypes.None;
                _atmosphericPresence = "None";
                _hasAtmosphere       = false;
            }
            else if (randValue <= 4)
            {
                AtmosphereType       = AtmosphereTypes.Thin;
                _atmosphericPresence = "Thin";
                _hasAtmosphere       = true;
            }
            else if (randValue <= 9)
            {
                AtmosphereType       = AtmosphereTypes.Moderate;
                _atmosphericPresence = "Moderate";
                _hasAtmosphere       = true;
            }
            else
            {
                AtmosphereType       = AtmosphereTypes.Heavy;
                _atmosphericPresence = "Heavy";
                _hasAtmosphere       = true;
            }

            // Generate Atmospheric Composition
            if (_hasAtmosphere)
            {
                randValue = Globals.RollD10() + atmosphericCompositionModifier;
                if (randValue <= 1 && !_forceInhabitable)
                {
                    _atmosphericComposition = "Deadly";
                    _atmosphereTainted      = false;
                    _atmospherePure         = false;
                }
                else if (randValue <= 2 && !_forceInhabitable)
                {
                    _atmosphericComposition = "Corrosive";
                    _atmosphereTainted      = false;
                    _atmospherePure         = false;
                }
                else if (randValue <= 5 && !_forceInhabitable)
                {
                    _atmosphericComposition = "Toxic";
                    _atmosphereTainted      = false;
                    _atmospherePure         = false;
                }
                else if (randValue <= 7)
                {
                    _atmosphericComposition = "Tainted";
                    _atmosphereTainted      = true;
                    _atmospherePure         = false;
                }
                else
                {
                    _atmosphericComposition = "Pure";
                    _atmosphereTainted      = false;
                    _atmospherePure         = true;
                }
            }
            else
            {
                _atmosphericComposition = "None";
                _atmosphereTainted      = false;
                _atmospherePure         = false;
            }

            // Generate Climate
            if (_hasAtmosphere)
            {
                int climateModifier = 0;
                if (_effectiveSystemZone == SystemZone.InnerCauldron)
                {
                    climateModifier -= 6;
                }
                else if (_effectiveSystemZone == SystemZone.OuterReaches)
                {
                    climateModifier += 6;
                }

                randValue = Globals.RollD10() + climateModifier;
                if (randValue <= 0 && !_forceInhabitable)
                {
                    ClimateType           = ClimateTypes.BurningWorld;
                    _climate              = "Burning World";
                    habitabilityModifier -= 7;
                    maxHabitabilityRoll   = 3;
                }
                else if (randValue <= 3)
                {
                    ClimateType           = ClimateTypes.HotWorld;
                    _climate              = "Hot World";
                    habitabilityModifier -= 2;
                }
                else if (randValue <= 7)
                {
                    ClimateType = ClimateTypes.TemperateWorld;
                    _climate    = "Temperate World";
                }
                else if (randValue <= 10 || _forceInhabitable)
                {
                    ClimateType           = ClimateTypes.ColdWorld;
                    _climate              = "Cold World";
                    habitabilityModifier -= 2;
                }
                else
                {
                    ClimateType           = ClimateTypes.IceWorld;
                    _climate              = "Ice World";
                    habitabilityModifier -= 7;
                    maxHabitabilityRoll   = 3;
                }
            }
            else
            {
                if (_effectiveSystemZone == SystemZone.InnerCauldron)
                {
                    _climate              = "Burning World";
                    habitabilityModifier -= 7;
                }
                else if (_effectiveSystemZone == SystemZone.OuterReaches)
                {
                    _climate              = "Ice World";
                    habitabilityModifier -= 7;
                }
                else if (Globals.RollD10() <= 5)
                {
                    _climate              = "Burning World";
                    habitabilityModifier -= 7;
                }
                else
                {
                    _climate              = "Ice World";
                    habitabilityModifier -= 7;
                }
            }

            // Generate Habitability
            bool chanceOfAdaptedLife = false;

            if (Globals.RollD100() <= 2) // Provide a tiny chance that life develops on worlds that don't normally support it
            {
                chanceOfAdaptedLife = true;
                maxHabitabilityRoll = 9999;
            }

            if ((_hasAtmosphere &&
                 (_atmosphereTainted || _atmospherePure)) ||
                chanceOfAdaptedLife)
            {
                if (_systemCreationRules.HavenBetterHabitability)
                {
                    habitabilityModifier += 2;
                }

                randValue = Globals.RollD10() + habitabilityModifier;
                if (randValue > maxHabitabilityRoll)
                {
                    randValue = maxHabitabilityRoll;
                }

                if (randValue <= 1)
                {
                    _habitabiliy = Habitabiliy.Inhospitable;
                }
                else if (randValue <= 3)
                {
                    _habitabiliy = Habitabiliy.TrappedWater;
                }
                else if (randValue <= 5)
                {
                    _habitabiliy = Habitabiliy.LiquidWater;
                }
                else if (randValue <= 7)
                {
                    _habitabiliy = Habitabiliy.LimitedEcosystem;
                }
                else
                {
                    _habitabiliy = Habitabiliy.Verdant;
                }
            }
            else
            {
                _habitabiliy = Habitabiliy.Inhospitable;
            }

            if (_forceInhabitable)
            {
                if (_habitabiliy != Habitabiliy.LimitedEcosystem && _habitabiliy != Habitabiliy.Verdant)
                {
                    _habitabiliy = Globals.RollD5() <= 2 ? Habitabiliy.LimitedEcosystem : Habitabiliy.Verdant;
                }
            }

            // Generate Landmasses
            bool addLandmasses = false;

            if (_habitabiliy == Habitabiliy.LiquidWater ||
                _habitabiliy == Habitabiliy.LimitedEcosystem ||
                _habitabiliy == Habitabiliy.Verdant)
            {
                if (Globals.RollD10() >= 4)
                {
                    addLandmasses = true;
                }
            }
            else if (Globals.RollD10() >= 8)
            {
                addLandmasses = true;
            }

            if (addLandmasses)
            {
                _numContinents = Globals.RollD5();
                int temp1 = Globals.RollD100();
                int temp2 = Globals.RollD100();
                _numIslands = temp1 < temp2 ? temp1 : temp2;
                if (effectivePlanetSize == EffectivePlanetSize.Small)
                {
                    _numIslands -= 15;
                    if (_numIslands > 20)
                    {
                        _numIslands = 10 + Globals.RollD10();
                    }
                }
                if (effectivePlanetSize == EffectivePlanetSize.Large)
                {
                    _numIslands -= 10;
                    if (_numIslands > 50)
                    {
                        _numIslands = 40 + Globals.RollD10();
                    }
                }
                if (_habitabiliy == Habitabiliy.Inhospitable || _habitabiliy == Habitabiliy.TrappedWater)
                {
                    _numIslands -= 30;
                }
                if (_numIslands < 0)
                {
                    _numIslands = 0;
                }
            }

            // Generate Environments
            if (/*_numContinents > 0 &&*/
                (_habitabiliy == Habitabiliy.LimitedEcosystem ||
                 _habitabiliy == Habitabiliy.Verdant))
            {
                int numTerritories = Globals.RollD5();
                if (effectivePlanetSize == EffectivePlanetSize.Small)
                {
                    numTerritories -= 2;
                }
                if (effectivePlanetSize == EffectivePlanetSize.Vast)
                {
                    numTerritories += 3;
                }
                if (_habitabiliy == Habitabiliy.Verdant)
                {
                    numTerritories += 2;
                }
                if (numTerritories < 1)
                {
                    numTerritories = 1;
                }
                _environment = new Environment(numTerritories);
                _environment.Generate();
            }
            else
            {
                _environment = new Environment(0);
            }

            // Generate Base Mineral Resources
            int numMineralResources;

            switch (effectivePlanetSize)
            {
            case EffectivePlanetSize.Small:
                numMineralResources = Globals.RollD5() - 2;
                if (numMineralResources < 0)
                {
                    numMineralResources = 0;
                }
                break;

            case EffectivePlanetSize.Large:
                numMineralResources = Globals.RollD5();
                break;

            case EffectivePlanetSize.Vast:
                numMineralResources = Globals.RollD10();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            numMineralResources += _systemCreationRules.NumExtraMineralResourcesPerPlanet;
            GenerateMineralResources(numMineralResources, mineralResourceAbundanceModifier, maximumMineralResourceAbundance);

            if (_systemCreationRules.ChanceForExtraExoticMaterialsPerPlanet)
            {
                GenerateExoticMaterialsResource(1, mineralResourceAbundanceModifier, maximumMineralResourceAbundance);
            }

            // Generate Additional Resources
            int numOrganicCompoundsFromTerritories = _environment.GetNumOrganicCompounds();

            for (int i = 0; i < numOrganicCompoundsFromTerritories; i++)
            {
                GenerateOrganicCompound();
            }

            int numAdditionalResources;

            switch (effectivePlanetSize)
            {
            case EffectivePlanetSize.Small:
                numAdditionalResources = Globals.RollD5() - 3;
                if (numAdditionalResources < 0)
                {
                    numAdditionalResources = 0;
                }
                break;

            case EffectivePlanetSize.Large:
                numAdditionalResources = Globals.RollD5() - 2;
                if (numAdditionalResources < 0)
                {
                    numAdditionalResources = 0;
                }
                break;

            case EffectivePlanetSize.Vast:
                numAdditionalResources = Globals.RollD5() - 1;
                if (numAdditionalResources < 0)
                {
                    numAdditionalResources = 0;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            for (int i = 0; i < numAdditionalResources; i++)
            {
                switch (Globals.RollD10())
                {
                case 1:
                case 2:
                    int bonusArcheotechAbundance = 0;
                    if (_systemCreationRules.RuinedEmpireIncreasedAbundanceArcheotechCaches)
                    {
                        bonusArcheotechAbundance += Globals.RollD10() + 5;
                    }
                    GenerateArcheotechCache(bonusArcheotechAbundance);
                    break;

                case 3:
                case 4:
                case 5:
                case 6:
                    GenerateMineralResources(1, mineralResourceAbundanceModifier, maximumMineralResourceAbundance);
                    break;

                case 7:
                case 8:
                    if (_habitabiliy == Habitabiliy.Verdant ||
                        _habitabiliy == Habitabiliy.LimitedEcosystem)
                    {
                        GenerateOrganicCompound();
                    }
                    else
                    {
                        i--;     // Re-roll this result
                    }
                    break;

                case 9:
                case 10:
                    int bonusXenotechAbundance = 0;
                    if (_systemCreationRules.RuinedEmpireIncreasedAbundanceXenosRuins)
                    {
                        bonusXenotechAbundance += Globals.RollD10() + 5;
                    }
                    GenerateXenosRuins(bonusXenotechAbundance);
                    break;
                }
            }

            // Generate Landmarks
            _environment.GenerateLandmarks(this, effectivePlanetSize);

            // Generate Inhabitants
            if ((_habitabiliy == Habitabiliy.Verdant ||
                 _habitabiliy == Habitabiliy.LimitedEcosystem))
            {
                if (Globals.RollD10() >= 8)
                {
                    GenerateInhabitants();
                }
            }
            else
            {
                if (Globals.RollD10() >= 10)
                {
                    GenerateInhabitants();
                }
            }
            if (_primitiveXenosNode.Children.Count < 1)
            {
                Children.Remove(_primitiveXenosNode);
            }

            // Generate Native Species
            int numNotableSpeciesFromTerritories = _environment.GetNumNotableSpecies();
            int numNativeSpecies = numNotableSpeciesFromTerritories;

            if (_habitabiliy == Habitabiliy.LimitedEcosystem)
            {
                numNativeSpecies += Globals.RollD5() + 1;
            }
            else if (_habitabiliy == Habitabiliy.Verdant)
            {
                numNativeSpecies += Globals.RollD5() + 5;
            }
            if (Properties.Settings.Default.UseKoronusBestiaryForXenosGeneration == false &&
                Properties.Settings.Default.UseStarsOfInequityForXenosGeneration == false)
            {
                numNativeSpecies = 0;
            }
            if (numNativeSpecies <= 0)
            {
                Children.Remove(_nativeSpeciesNode);
            }
            else
            {
                WorldType worldType = WorldType.TemperateWorld;
                if (ClimateType == ClimateTypes.IceWorld)
                {
                    worldType = WorldType.IceWorld;
                }
                if (ClimateType == ClimateTypes.BurningWorld)
                {
                    worldType = WorldType.VolcanicWorld;
                }
                if (ClimateType == ClimateTypes.HotWorld && Globals.RollD10() <= 6)
                {
                    worldType = WorldType.DesertWorld;
                }
                if (ClimateType == ClimateTypes.ColdWorld && Globals.RollD10() <= 6)
                {
                    worldType = WorldType.IceWorld;
                }
                WorldType = worldType;
                for (int i = 0; i < numNativeSpecies; i++)
                {
                    List <WorldType> notableSpeciesTerrainTypes = _environment.GetWorldTypesForNotableSpecies(this);
                    if (notableSpeciesTerrainTypes.Count >= i + 1)
                    {
                        worldType = notableSpeciesTerrainTypes[i];
                    }
                    _nativeSpeciesNode.AddXenos(worldType);
                }
            }
        }