Example #1
0
        public ResourceQuantity Evaluate(object host)
        {
            var q = new ResourceQuantity();

            foreach (var kvp in this)
            {
                q.Add(kvp.Key, kvp.Value.Evaluate(host));
            }
            return(q);
        }
Example #2
0
        // TODO - status messages for the GUI
        private void PlaceEmpire(Galaxy gal, Empire emp, PRNG dice)
        {
            if (AllSystemsExplored)
            {
                // set all systems explored
                foreach (var sys in gal.StarSystemLocations.Select(ssl => ssl.Item))
                {
                    sys.ExploredByEmpires.Add(emp);
                }
            }

            // give empire starting techs
            Galaxy.Current.CleanGameState();             // need to know what the techs in the game are!
            foreach (var tech in Mod.Current.Technologies.Where(t => !t.IsRacial || emp.Abilities().Any(a => a.Rule.Matches("Tech Area") && a.Value1 == t.RacialTechID)))
            {
                switch (StartingTechnologyLevel)
                {
                case StartingTechnologyLevel.Low:
                    emp.ResearchedTechnologies[tech] = tech.StartLevel;
                    break;

                case StartingTechnologyLevel.Medium:
                    emp.ResearchedTechnologies[tech] = Math.Max(tech.StartLevel, tech.RaiseLevel);
                    break;

                case StartingTechnologyLevel.High:
                    emp.ResearchedTechnologies[tech] = tech.MaximumLevel;
                    break;
                }
            }

            // give empire starting resources and storage capacity
            foreach (var r in Resource.All.Where(r => r.IsGlobal))
            {
                emp.StoredResources.Add(r, StartingResources);
                emp.IntrinsicResourceStorage.Add(r, ResourceStorage);
            }

            // give empire starting research
            emp.BonusResearch = StartingResearch + (int)(ResearchPointsPerUnspentEmpirePoint * (EmpirePoints - emp.PrimaryRace.Traits.Sum(q => q.Cost)));

            // TODO - moddable colony techs?
            string colonyTechName = null;

            if ((emp.PrimaryRace.NativeSurface) == "Rock")
            {
                colonyTechName = "Rock Planet Colonization";
            }
            else if ((emp.PrimaryRace.NativeSurface) == "Ice")
            {
                colonyTechName = "Ice Planet Colonization";
            }
            else if ((emp.PrimaryRace.NativeSurface) == "Gas Giant")
            {
                colonyTechName = "Gas Giant Colonization";
            }
            var colonyTech = Mod.Current.Technologies.SingleOrDefault(t => t.Name == colonyTechName);

            if (colonyTech != null && emp.ResearchedTechnologies[colonyTech] < 1)
            {
                emp.ResearchedTechnologies[colonyTech] = 1;
            }

            // find facilities to place on homeworlds
            var facils = emp.UnlockedItems.OfType <FacilityTemplate>();
            var sy     = facils.WithMax(facil => facil.GetAbilityValue("Space Yard", 2).ToInt()).LastOrDefault();
            var sp     = facils.LastOrDefault(facil => facil.HasAbility("Spaceport"));
            var rd     = facils.LastOrDefault(facil => facil.HasAbility("Supply Generation"));
            var min    = facils.WithMax(facil => facil.GetAbilityValue("Resource Generation - Minerals").ToInt()).LastOrDefault();
            var org    = facils.WithMax(facil => facil.GetAbilityValue("Resource Generation - Organics").ToInt()).LastOrDefault();
            var rad    = facils.WithMax(facil => facil.GetAbilityValue("Resource Generation - Radioactives").ToInt()).LastOrDefault();
            var res    = facils.WithMax(facil => facil.GetAbilityValue("Point Generation - Research").ToInt()).LastOrDefault();
            // TODO - game setup option for intel facilities on homeworlds? HomeworldStartingFacilities.txt ala se5?

            // SY rate, for colonies
            var rate = new ResourceQuantity();

            if (sy != null)
            {
                // TODO - define mappings between SY ability numbers and resource names in a mod file
                rate.Add(Resource.Minerals, sy.GetAbilityValue("Space Yard", 2, true, true, a => a.Value1 == "1").ToInt());
                rate.Add(Resource.Organics, sy.GetAbilityValue("Space Yard", 2, true, true, a => a.Value1 == "2").ToInt());
                rate.Add(Resource.Radioactives, sy.GetAbilityValue("Space Yard", 2, true, true, a => a.Value1 == "3").ToInt());
            }

            // build connectivity graph for computing warp distance
            var graph = new ConnectivityGraph <StarSystem>();

            foreach (var s in Galaxy.Current.StarSystemLocations.Select(ssl => ssl.Item))
            {
                graph.Add(s);
            }
            foreach (var s in Galaxy.Current.StarSystemLocations.Select(ssl => ssl.Item))
            {
                foreach (var wp in s.FindSpaceObjects <WarpPoint>())
                {
                    graph.Connect(s, wp.TargetStarSystemLocation.Item, true);
                }
            }

            for (int i = 0; i < HomeworldsPerEmpire; i++)
            {
                // TODO - respect Empire Placement and Max Homeworld Dispersion settings
                var planets   = gal.StarSystemLocations.SelectMany(ssl => ssl.Item.FindSpaceObjects <Planet>(p => p.Owner == null && p.MoonOf == null));
                var okSystems = gal.StarSystemLocations.Select(ssl => ssl.Item).Where(sys => sys.EmpiresCanStartIn);
                if (i > 0)
                {
                    // make sure subsequent homeworlds are placed within a limited number of warps from the first homeworld
                    okSystems = okSystems.Where(sys => graph.ComputeDistance(sys, emp.OwnedSpaceObjects.OfType <Planet>().First().FindStarSystem()) <= MaxHomeworldDispersion);
                }
                switch (EmpirePlacement)
                {
                case EmpirePlacement.CanStartInSameSystem:
                    // no further filtering
                    break;

                case EmpirePlacement.DifferentSystems:
                    // filter to systems containing no other empires' homeworlds
                    okSystems = okSystems.Where(sys => !sys.FindSpaceObjects <Planet>(p => p.Owner != null && p.Owner != emp).Any());
                    break;

                case EmpirePlacement.Equidistant:
                    // filter to systems containing no other empires' homeworlds
                    okSystems = okSystems.Where(sys => !sys.FindSpaceObjects <Planet>(p => p.Owner != null && p.Owner != emp).Any());
                    // filter to systems that are the maximum distance away from any other empire's homeworlds
                    var otherEmpireHomeSystems = gal.StarSystemLocations.SelectMany(ssl => ssl.Item.FindSpaceObjects <Planet>(p => p.Owner != null && p.Owner != emp).Select(p => p.FindStarSystem()).Distinct()).ToArray();
                    okSystems = okSystems.WithMax(sys => otherEmpireHomeSystems.Min(o => graph.ComputeDistance(sys, o)));
                    break;
                }
                okSystems = okSystems.ToArray();
                if (!okSystems.Any())
                {
                    // replace an inhospitable system with a hospitable one
                    var convertSys = gal.StarSystemLocations.Select(ssl => ssl.Item).Where(sys => !sys.EmpiresCanStartIn).PickRandom(dice);
                    if (convertSys == null)
                    {
                        throw new Exception("No suitable system found to place " + emp + "'s homeworld #" + (i + 1) + ". (Try increasing the number of star systems.)");
                    }
                    var newSys = Mod.Current.StarSystemTemplates.Where(q => q.EmpiresCanStartIn).PickRandom(dice).Instantiate();
                    var sid    = convertSys.ID;
                    newSys.CopyTo(convertSys);
                    convertSys.ID   = sid;
                    convertSys.Name = Mod.Current.StarSystemNames.Except(gal.StarSystemLocations.Select(q => q.Item.Name)).PickRandom(dice);
                    foreach (var l in Galaxy.Current.StarSystemLocations)
                    {
                        foreach (var wp in l.Item.FindSpaceObjects <WarpPoint>().Where(q => q.Target.StarSystem == convertSys).ToArray())
                        {
                            wp.Dispose();
                            WarpPointPlacementStrategy.PlaceWarpPoints(Galaxy.Current.StarSystemLocations.Single(q => q.Item == convertSys), l);
                        }
                    }
                    GalaxyTemplate.NameStellarObjects(convertSys);
                    okSystems = new[] { convertSys };
                }
                Planet hw;
                planets = planets.Where(p => okSystems.Contains(p.FindStarSystem()));
                if (!planets.Any())
                {
                    // make sure we're placing the homeworld in a system with at least one empty sector
                    okSystems = okSystems.Where(sys2 => sys2.Sectors.Any(sec => !sec.SpaceObjects.Any()));

                    if (!okSystems.Any())
                    {
                        throw new Exception("No suitable system found to place " + emp + "'s homeworld #" + (i + 1) + ". (Try regenerating the map or increasing the number of star systems.)");
                    }

                    // make brand new planet in an OK system
                    var sys     = okSystems.PickRandom(dice);
                    var nextNum = sys.FindSpaceObjects <Planet>(p => p.MoonOf == null).Count() + 1;
                    hw = MakeHomeworld(emp, sys.Name + " " + nextNum.ToRomanNumeral(), dice);
                    var okSectors = sys.Sectors.Where(sector => !sector.SpaceObjects.Any());
                    okSectors.PickRandom(dice).Place(hw);
                }
                else
                {
                    hw = planets.PickRandom(dice);
                }
                if (hw.Surface != emp.PrimaryRace.NativeSurface || hw.Atmosphere != emp.PrimaryRace.NativeAtmosphere || hw.Size != HomeworldSize)
                {
                    var replacementHomeworld = MakeHomeworld(emp, hw.Name, dice);
                    replacementHomeworld.CopyTo(hw);
                }
                hw.ResourceValue[Resource.Minerals] = hw.ResourceValue[Resource.Organics] = hw.ResourceValue[Resource.Radioactives] = HomeworldValue;
                hw.Colony = new Colony
                {
                    Owner             = emp,
                    ConstructionQueue = new ConstructionQueue(hw),
                    IsHomeworld       = true,
                };
                hw.AddPopulation(emp.PrimaryRace, hw.Size.MaxPopulation);
                if (sy != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                {
                    hw.Colony.Facilities.Add(sy.Instantiate());
                }
                if (sp != null && hw.Colony.Facilities.Count < hw.MaxFacilities && (!emp.HasAbility("No Spaceports") || sp.Abilities.Count > 1))
                {
                    // natural merchants get spaceports only if spaceports have more than one ability
                    // of course, if the other abilities are *penalties*... oh well, they can scrap them!
                    hw.Colony.Facilities.Add(sp.Instantiate());
                }
                if (rd != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                {
                    hw.Colony.Facilities.Add(rd.Instantiate());
                }
                var lastCount = 0;
                while (hw.Colony.Facilities.Count < hw.MaxFacilities && hw.Colony.Facilities.Count > lastCount)
                {
                    lastCount = hw.Colony.Facilities.Count;

                    if (min != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                    {
                        hw.Colony.Facilities.Add(min.Instantiate());
                    }
                    if (org != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                    {
                        hw.Colony.Facilities.Add(org.Instantiate());
                    }
                    if (rad != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                    {
                        hw.Colony.Facilities.Add(rad.Instantiate());
                    }

                    // no research facilities needed at max tech!
                    if (StartingTechnologyLevel != StartingTechnologyLevel.High)
                    {
                        if (res != null && hw.Colony.Facilities.Count < hw.MaxFacilities)
                        {
                            hw.Colony.Facilities.Add(res.Instantiate());
                        }
                    }
                }
                foreach (var f in hw.Colony.Facilities)
                {
                    f.ConstructionProgress = f.Cost;
                }
            }

            // mark home systems explored
            foreach (var sys in gal.StarSystemLocations.Select(ssl => ssl.Item))
            {
                if (!sys.ExploredByEmpires.Contains(emp) && sys.FindSpaceObjects <Planet>().Any(planet => planet.Owner == emp))
                {
                    sys.ExploredByEmpires.Add(emp);
                }
            }

            // in case two empires started in the same system
            foreach (var x in gal.FindSpaceObjects <ISpaceObject>().Owned().ToArray())
            {
                x.UpdateEmpireMemories();
            }
        }
Example #3
0
        public ModSettings()
        {
            DefaultColonyConstructionRate = new ResourceQuantity();
            // TODO - moddable default colony construction rate
            DefaultColonyConstructionRate.Add(Resource.Minerals, 2000);
            DefaultColonyConstructionRate.Add(Resource.Organics, 2000);
            DefaultColonyConstructionRate.Add(Resource.Radioactives, 2000);

            PopulationModifiers = new SortedDictionary <long, PopulationModifier>();

            // TODO - split apart production and construction modifiers as a mod option?
            MoodProductivityModifiers = new Dictionary <Mood, int>();

            // TODO - moddable mood reproduction modifiers
            MoodReproductionModifiers = new Dictionary <Mood, int>();
            MoodReproductionModifiers.Add(Mood.Rioting, -999);
            MoodReproductionModifiers.Add(Mood.Angry, -5);
            MoodReproductionModifiers.Add(Mood.Unhappy, -2);
            MoodReproductionModifiers.Add(Mood.Indifferent, 0);
            MoodReproductionModifiers.Add(Mood.Happy, 2);
            MoodReproductionModifiers.Add(Mood.Jubilant, 5);
            MoodReproductionModifiers.Add(Mood.Emotionless, 2);

            // TODO - moddable mood construction modifiers
            MoodConstructionModifiers = new Dictionary <Mood, int>();
            MoodConstructionModifiers.Add(Mood.Rioting, 0);
            MoodConstructionModifiers.Add(Mood.Angry, 100);
            MoodConstructionModifiers.Add(Mood.Unhappy, 100);
            MoodConstructionModifiers.Add(Mood.Indifferent, 100);
            MoodConstructionModifiers.Add(Mood.Happy, 100);
            MoodConstructionModifiers.Add(Mood.Jubilant, 100);
            MoodConstructionModifiers.Add(Mood.Emotionless, 100);

            // TODO - moddable mood thresholds
            MoodThresholds = new Dictionary <Mood, int>();
            MoodThresholds.Add(Mood.Rioting, 750);
            MoodThresholds.Add(Mood.Angry, 600);
            MoodThresholds.Add(Mood.Unhappy, 450);
            MoodThresholds.Add(Mood.Indifferent, 300);
            MoodThresholds.Add(Mood.Happy, 150);
            MoodThresholds.Add(Mood.Jubilant, 0);

            // TODO - moddable planetary conditions thresholds
            ConditionsThresholds = new Dictionary <Conditions, int>();
            ConditionsThresholds.Add(Conditions.Deadly, 0);
            ConditionsThresholds.Add(Conditions.Harsh, 20);
            ConditionsThresholds.Add(Conditions.Unpleasant, 35);
            ConditionsThresholds.Add(Conditions.Average, 50);
            ConditionsThresholds.Add(Conditions.Mild, 65);
            ConditionsThresholds.Add(Conditions.Good, 80);
            ConditionsThresholds.Add(Conditions.Optimal, 95);

            // TODO - moddable planetary conditions modifiers
            ConditionsReproductionModifiers = new Dictionary <Conditions, int>();
            ConditionsReproductionModifiers.Add(Conditions.Deadly, -20);
            ConditionsReproductionModifiers.Add(Conditions.Harsh, -5);
            ConditionsReproductionModifiers.Add(Conditions.Unpleasant, -2);
            ConditionsReproductionModifiers.Add(Conditions.Average, 0);
            ConditionsReproductionModifiers.Add(Conditions.Mild, 2);
            ConditionsReproductionModifiers.Add(Conditions.Good, 5);
            ConditionsReproductionModifiers.Add(Conditions.Optimal, 8);

            IntroSongs    = new List <string>();
            GameplaySongs = new List <string>();
            CombatSongs   = new List <string>();
            VictorySongs  = new List <string>();
            DefeatSongs   = new List <string>();

            VictoryPictures = new List <string>();
            DefeatPictures  = new List <string>();

            ValueChangeFrequency = 10;
        }