From: <ve...@us...> - 2014-01-26 16:17:36
|
Revision: 6735 http://sourceforge.net/p/freeorion/code/6735 Author: vezzra Date: 2014-01-26 16:17:30 +0000 (Sun, 26 Jan 2014) Log Message: ----------- Scripted universe generation: - fixed naming of planets (when asteroid belts have been converted to homeworlds, they weren't renamed correctly) - removed UniverseGenerator::CreateUniverse function and moved its contents into PythonUniverseGenerator::GenerateUniverse - added/exposed to Python: Meter::LARGE_VALUE, PlanetMakeOutpost, PlanetMakeColony - moved colonization code from ServerApp.cpp to new Planet class member function Colonize (required for PlanetMakeOutpost, PlanetMakeColony) - some tweaks/fixes Modified Paths: -------------- trunk/FreeOrion/default/UniverseGenerator.py trunk/FreeOrion/server/ServerApp.cpp trunk/FreeOrion/universe/Planet.cpp trunk/FreeOrion/universe/Planet.h trunk/FreeOrion/universe/PythonUniverseGenerator.cpp trunk/FreeOrion/universe/UniverseGenerator.cpp trunk/FreeOrion/universe/UniverseGenerator.h Modified: trunk/FreeOrion/default/UniverseGenerator.py =================================================================== --- trunk/FreeOrion/default/UniverseGenerator.py 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/default/UniverseGenerator.py 2014-01-26 16:17:30 UTC (rev 6735) @@ -8,6 +8,7 @@ import foUniverseGenerator as fo + #tuples of consonants and vowels for random name generation consonants = ("b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z") vowels = ("a", "e", "i", "o", "u") @@ -220,23 +221,37 @@ return planet_type # Generate a new planet in specified system and orbit -def generatePlanet(planet_size, planet_type, system, orbit, number): - +def generatePlanet(planet_size, planet_type, system, orbit): try: - if planet_type == fo.planetType.asteroids: - name = fo.userString("PL_ASTEROID_BELT_OF_SYSTEM") - name = name.replace("%1%", fo.getName(system)) - else: - name = fo.getName(system) + " " + fo.romanNumber(number) - planet = fo.createPlanet(planet_size, planet_type, system, orbit, name) - + planet = fo.createPlanet(planet_size, planet_type, system, orbit, "") except: planet = fo.invalidObject(); print "Python generatePlanet: Create planet failed" print sys.exc_info()[1] - return planet +# Sets the names of the planets of the specified system +# planet name is system name + planet number (as roman number) +# unless it's an asteroid belt, in that case name is system +# name + "asteroid belt" (localized) +def namePlanets(system): + planet_number = 1 + # iterate over all planets in the system + for planet in fo.sysGetPlanets(system): + # use different naming methods for "normal" planets and asteroid belts + if fo.planetGetType(planet) == fo.planetType.asteroids: + # get localized text from stringtable + name = fo.userString("PL_ASTEROID_BELT_OF_SYSTEM") + # %1% parameter in the localized string is the system name + name = name.replace("%1%", fo.getName(system)) + else: + # set name to system name + planet number as roman number... + name = fo.getName(system) + " " + fo.romanNumber(planet_number) + # ...and increase planet number + planet_number = planet_number + 1 + # do the actual renaming + fo.setName(planet, name) + # Checks if a system is too close to the other home systems # Home systems should be at least 200 units (linear distance) # and 2 jumps apart @@ -318,7 +333,7 @@ # set to suitable values later if len(fo.sysGetPlanets(candidate)) == 0: print "Home system #", len(home_systems), "has no planets, adding one" - if generatePlanet(random.choice(real_planet_sizes), random.choice(planet_types), candidate, random.randint(0, fo.sysGetNumOrbits(candidate) - 1), 1) == fo.invalidObject(): + if generatePlanet(random.choice(real_planet_sizes), random.choice(planet_types), candidate, random.randint(0, fo.sysGetNumOrbits(candidate) - 1)) == fo.invalidObject(): # generate planet failed, throw an exception raise Exception("Python generateHomeSystemList: couldn't create planet in home system") @@ -478,16 +493,13 @@ system = generateSystem(position) systems.append(system) star_type = fo.sysGetStarType(system) # needed to determine planet size (and maybe in future also type?) - planet_number = 1 # needed to make up the planet named for orbit in range(0, fo.sysGetNumOrbits(system)): # check for each orbit if a planet shall be created by determining planet size planet_size = calcPlanetSize(star_type, orbit) if planet_size in planet_sizes: # ok, we want a planet, determine planet type and generate the planet planet_type = calcPlanetType(star_type, orbit, planet_size) - if generatePlanet(planet_size, planet_type, system, orbit, planet_number) != fo.invalidObject(): - # new planet successfully created, increase planet number - planet_number = planet_number + 1 + generatePlanet(planet_size, planet_type, system, orbit) print len(systems), "systems generated and populated" # generate Starlanes @@ -497,7 +509,7 @@ print "Generate list of home systems..." home_systems = generateHomeSystemList(total_players, systems) print "...systems choosen:", home_systems - + # store list of possible empire names in global container global empire_names print "Load list of empire names..." @@ -514,11 +526,12 @@ home_system = home_systems.pop() setupEmpire(empire, psd.empireName, home_system, psd.startingSpecies, psd.playerName) - # Let UniverseGenerator::CreateUniverse do the rest that can't been implemented - # with Python scripts yet - fo.createUniverse(gsd.size, gsd.shape, gsd.age, - gsd.starlaneFrequency, gsd.planetDensity, gsd.specialsFrequency, - gsd.monsterFrequency, gsd.nativeFrequency, system_positions, - psd_list) + # iterate over all systems and name their planets + # this needs to be done after empire home systems have been set, as + # during that process asteroid belts might be changed into planets, + # and we need to know the final type of a planet to name it + print "Set planet names" + for system in systems: + namePlanets(system) print "Python Universe Generator completed" Modified: trunk/FreeOrion/server/ServerApp.cpp =================================================================== --- trunk/FreeOrion/server/ServerApp.cpp 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/server/ServerApp.cpp 2014-01-26 16:17:30 UTC (rev 6735) @@ -1758,11 +1758,6 @@ Logger().errorStream() << "ColonizePlanet ship has no species"; return false; } - const Species* species = GetSpecies(species_name); - if (!species) { - Logger().errorStream() << "ColonizePlanet couldn't get species with name: " << species_name; - return false; - } const ShipDesign* design = ship->Design(); if (!design) { @@ -1785,11 +1780,13 @@ // all checks passed. proceed with colonization. + // colonize planet by calling Planet class Colonize member function + // do this BEFORE destroying the ship, since species_name is a const reference to Ship::m_species_name + if (!planet->Colonize(empire_id, species_name, colonist_capacity)) { + Logger().errorStream() << "ColonizePlanet: couldn't colonize planet"; + return false; + } - planet->Reset(); - if (colonist_capacity > 0.0) - planet->SetSpecies(species_name); // do this BEFORE destroying the ship, since species_name is a const reference to Ship::m_species_name - TemporaryPtr<System> system = GetSystem(ship->SystemID()); // destroy colonizing ship, and its fleet if now empty @@ -1807,38 +1804,6 @@ system->Remove(ship->ID()); GetUniverse().RecursiveDestroy(ship->ID()); - - // find a focus to give planets by default. use first defined available focus. - // the planet's AvailableFoci function should return a vector of all names of - // available foci. - std::vector<std::string> available_foci = planet->AvailableFoci(); - if (!available_foci.empty()) { - bool found_preference = false; - for (std::vector<std::string>::const_iterator it = available_foci.begin(); - it != available_foci.end(); ++it) - { - if (!it->empty() && *it == species->PreferredFocus()) { - planet->SetFocus(*it); - found_preference = true; - break; - } - } - - if (!found_preference) - planet->SetFocus(*available_foci.begin()); - } - - planet->GetMeter(METER_POPULATION)->SetCurrent(colonist_capacity); - planet->GetMeter(METER_TARGET_POPULATION)->SetCurrent(colonist_capacity); - planet->BackPropegateMeters(); - - planet->SetOwner(empire_id); - - std::vector<TemporaryPtr<Building> > buildings = Objects().FindObjects<Building>(planet->BuildingIDs()); - for (std::vector<TemporaryPtr<Building> >::iterator building_it = buildings.begin(); - building_it != buildings.end(); ++building_it) - { (*building_it)->SetOwner(empire_id); } - return true; } Modified: trunk/FreeOrion/universe/Planet.cpp =================================================================== --- trunk/FreeOrion/universe/Planet.cpp 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/universe/Planet.cpp 2014-01-26 16:17:30 UTC (rev 6735) @@ -654,6 +654,68 @@ SetOwner(conquerer); } +bool Planet::Colonize(int empire_id, const std::string& species_name, double population) { + const Species* species = 0; + + // if desired pop > 0, we want a colony, not an outpost, so we need to do some checks + if (population > 0.0) { + // check if specified species exists and get reference + species = GetSpecies(species_name); + if (!species) { + Logger().errorStream() << "Planet::Colonize couldn't get species with name: " << species_name; + return false; + } + // check if specified species can colonize this planet + if (population > 0.0 && EnvironmentForSpecies(species_name) < PE_HOSTILE) { + Logger().errorStream() << "Planet::Colonize: can't colonize planet with species " << species_name; + return false; + } + } + + // reset the planet to unowned/unpopulated + Reset(); + + // if desired pop > 0, we want a colony, not an outpost, so we have to set the colony species + if (population > 0.0) + SetSpecies(species_name); + + // find a default focus. use first defined available focus. + // AvailableFoci function should return a vector of all names of + // available foci. + std::vector<std::string> available_foci = AvailableFoci(); + if (species && !available_foci.empty()) { + bool found_preference = false; + for (std::vector<std::string>::const_iterator it = available_foci.begin(); + it != available_foci.end(); ++it) + { + if (!it->empty() && *it == species->PreferredFocus()) { + SetFocus(*it); + found_preference = true; + break; + } + } + + if (!found_preference) + SetFocus(*available_foci.begin()); + } + + // set colony population + GetMeter(METER_POPULATION)->SetCurrent(population); + GetMeter(METER_TARGET_POPULATION)->SetCurrent(population); + BackPropegateMeters(); + + // set specified empire as owner + SetOwner(empire_id); + + // if there are buildings on the planet, set the specified empire as their owner too + std::vector<TemporaryPtr<Building> > buildings = Objects().FindObjects<Building>(BuildingIDs()); + for (std::vector<TemporaryPtr<Building> >::iterator building_it = buildings.begin(); + building_it != buildings.end(); ++building_it) + { (*building_it)->SetOwner(empire_id); } + + return true; +} + void Planet::SetIsAboutToBeColonized(bool b) { bool initial_status = m_is_about_to_be_colonized; if (b == initial_status) return; Modified: trunk/FreeOrion/universe/Planet.h =================================================================== --- trunk/FreeOrion/universe/Planet.h 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/universe/Planet.h 2014-01-26 16:17:30 UTC (rev 6735) @@ -159,6 +159,7 @@ virtual void Depopulate(); void Conquer(int conquerer); ///< Called during combat when a planet changes hands + bool Colonize(int empire_id, const std::string& species_name, double population); ///< Called during colonization handling to do the actual colonizing void SetIsAboutToBeColonized(bool b); ///< Called during colonization when a planet is about to be colonized void ResetIsAboutToBeColonized(); ///< Called after colonization, to reset the number of prospective colonizers to 0 void SetIsAboutToBeInvaded(bool b); ///< Marks planet as being invaded or not, depending on whether \a b is true or false Modified: trunk/FreeOrion/universe/PythonUniverseGenerator.cpp =================================================================== --- trunk/FreeOrion/universe/PythonUniverseGenerator.cpp 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/universe/PythonUniverseGenerator.cpp 2014-01-26 16:17:30 UTC (rev 6735) @@ -14,6 +14,7 @@ #include "../util/Logger.h" #include "../util/Random.h" #include "../util/i18n.h" +#include "../util/OptionsDB.h" #include "../python/PythonSetWrapper.h" #include "../python/PythonWrappers.h" #include "../parse/Parse.h" @@ -90,6 +91,9 @@ double MinSystemSeparation() { return MIN_SYSTEM_SEPARATION; } + float LargeMeterValue() + { return Meter::LARGE_VALUE; } + // Universe tables const std::vector<int>& g_base_star_type_dist = UniverseDataTables()["BaseStarTypeDist"][0]; const std::vector<std::vector<int> >& g_universe_age_mod_to_star_type_dist = UniverseDataTables()["UniverseAgeModToStarTypeDist"]; @@ -652,7 +656,16 @@ Logger().errorStream() << "PythonUniverseGenerator::PlanetSetType: Couldn't get planet with ID " << planet_id; return; } + planet->SetType(planet_type); + if (planet_type == PT_ASTEROIDS) + planet->SetSize(SZ_ASTEROIDS); + else if (planet_type == PT_GASGIANT) + planet->SetSize(SZ_GASGIANT); + else if (planet->Size() == SZ_ASTEROIDS) + planet->SetSize(SZ_TINY); + else if (planet->Size() == SZ_GASGIANT) + planet->SetSize(SZ_HUGE); } PlanetSize PlanetGetSize(int planet_id) { @@ -670,7 +683,14 @@ Logger().errorStream() << "PythonUniverseGenerator::PlanetSetSize: Couldn't get planet with ID " << planet_id; return; } + planet->SetSize(planet_size); + if (planet_size == SZ_ASTEROIDS) + planet->SetType(PT_ASTEROIDS); + else if (planet_size == SZ_GASGIANT) + planet->SetType(PT_GASGIANT); + else if ((planet->Type() == PT_ASTEROIDS) || (planet->Type() == PT_GASGIANT)) + planet->SetType(PT_BARREN); } object PlanetGetSpecies(int planet_id) { @@ -723,6 +743,44 @@ return py_foci; } + bool PlanetMakeOutpost(int planet_id, int empire_id) { + TemporaryPtr<Planet> planet = GetPlanet(planet_id); + if (!planet) { + Logger().errorStream() << "PythonUniverseGenerator::PlanetMakeOutpost: couldn't get planet with ID:" << planet_id; + return false; + } + + if (!Empires().Lookup(empire_id)) { + Logger().errorStream() << "PythonUniverseGenerator::PlanetMakeOutpost: couldn't get empire with ID " << empire_id; + return false; + } + + return planet->Colonize(empire_id, "", 0.0); + } + + bool PlanetMakeColony(int planet_id, int empire_id, const std::string& species, double population) { + TemporaryPtr<Planet> planet = GetPlanet(planet_id); + if (!planet) { + Logger().errorStream() << "PythonUniverseGenerator::PlanetMakeColony: couldn't get planet with ID:" << planet_id; + return false; + } + + if (!Empires().Lookup(empire_id)) { + Logger().errorStream() << "PythonUniverseGenerator::PlanetMakeColony: couldn't get empire with ID " << empire_id; + return false; + } + + if (!GetSpecies(species)) { + Logger().errorStream() << "PythonUniverseGenerator::PlanetMakeColony: couldn't get species with name: " << species; + return false; + } + + if (population < 0.0) + population = 0.0; + + return planet->Colonize(empire_id, species, population); + } + // Misc. helper functions/wrappers // // Wrapper function for i18n::RomanNumber @@ -771,6 +829,7 @@ def("allEmpires", AllEmpires); def("invalidObject", InvalidObjectID); def("minSystemSeparation", MinSystemSeparation); + def("largeMeterValue", LargeMeterValue); def("baseStarTypeDist", BaseStarTypeDist); def("universeAgeModToStarTypeDist", UniverseAgeModToStarTypeDist); @@ -834,9 +893,9 @@ def("planetGetFocus", PlanetGetFocus); def("planetSetFocus", PlanetSetFocus); def("planetAvailableFoci", PlanetAvailableFoci); + def("planetMakeOutpost", PlanetMakeOutpost); + def("planetMakeColony", PlanetMakeColony); - def("createUniverse", CreateUniverse); - // Enums FreeOrionPython::WrapGameStateEnums(); @@ -857,9 +916,6 @@ static dict s_python_namespace = dict(); static object s_python_module = object(); - // Object storing the main Python createUniverse function callable - static object PythonCreateUniverse = object(); - // Helper function for executing a Python script bool PythonExecScript(const std::string script) { try { object ignored = exec(script.c_str(), s_python_namespace, s_python_namespace); } @@ -951,7 +1007,6 @@ try { // import universe generator script file s_python_module = import("UniverseGenerator"); - PythonCreateUniverse = s_python_module.attr("createUniverse"); } catch (error_already_set err) { Logger().errorStream() << "Unable to import universe generator script"; @@ -967,15 +1022,29 @@ Py_Finalize(); s_python_namespace = dict(); s_python_module = object(); - PythonCreateUniverse = object(); Logger().debugStream() << "Cleaned up universe generator Python interface"; } + + // Wraps call to the main Python universe generator function + void PythonCreateUniverse() { + object f = s_python_module.attr("createUniverse"); + if (!f) { + Logger().errorStream() << "Unable to call Python function createUniverse "; + return; + } + try { f(); } + catch (error_already_set err) { + PyErr_Print(); + } + } } void GenerateUniverse(GalaxySetupData& galaxy_setup_data, const std::map<int, PlayerSetupData>& player_setup_data) { + Universe& universe = GetUniverse(); + // Set the global GalaxySetupData reference and PlayerSetupData map // to the instances we received g_galaxy_setup_data = &galaxy_setup_data; @@ -990,8 +1059,7 @@ boost::hash<std::string> string_hash; std::size_t h = string_hash(g_galaxy_setup_data->m_seed); seed = static_cast<unsigned int>(h); - } catch (...) { - } + } catch (...) {} } Seed(seed); Logger().debugStream() << "GenerateUniverse with seed: " << seed; @@ -1000,19 +1068,52 @@ PythonInit(); // Reset the universe object for a new universe - GetUniverse().ResetUniverse(); + universe.ResetUniverse(); // Add predefined ship designs to universe GetPredefinedShipDesignManager().AddShipDesignsToUniverse(); // Initialize empire objects for each player InitEmpires(player_setup_data); - // Call the main Python universe generator script - try { - PythonCreateUniverse(); + // Call the main Python universe generator function + PythonCreateUniverse(); + + // TEMPORARY: Use legacy universe generation funtions for + // all the stuff that hasn't been ported to Python yet + Logger().debugStream() << "Generating Natives"; + GenerateNatives(universe, galaxy_setup_data.m_native_freq); + Logger().debugStream() << "Generating Space Monsters"; + GenerateSpaceMonsters(universe, galaxy_setup_data.m_monster_freq); + Logger().debugStream() << "Adding Starting Specials"; + AddStartingSpecials(universe, galaxy_setup_data.m_specials_freq); + + Logger().debugStream() << "Applying first turn effects and updating meters"; + + // Apply effects for 1st turn. + universe.ApplyAllEffectsAndUpdateMeters(); + // Set active meters to targets or maxes after first meter effects application + SetActiveMetersToTargetMaxCurrentValues(universe.Objects()); + universe.BackPropegateObjectMeters(); + Empires().BackPropegateMeters(); + + Logger().debugStream() << "Re-applying first turn meter effects and updating meters"; + + // Re-apply meter effects, so that results depending on meter values can be + // re-checked after initial setting of those meter values + universe.ApplyMeterEffectsAndUpdateMeters(); + // Re-set active meters to targets after re-application of effects + SetActiveMetersToTargetMaxCurrentValues(universe.Objects()); + // Set the population of unowned planets to a random fraction of their target values. + SetNativePopulationValues(universe.Objects()); + + universe.BackPropegateObjectMeters(); + Empires().BackPropegateMeters(); + + if (GetOptionsDB().Get<bool>("verbose-logging")) { + Logger().debugStream() << "!!!!!!!!!!!!!!!!!!! After setting active meters to targets"; + Logger().debugStream() << universe.Objects().Dump(); } - catch (error_already_set err) { - PyErr_Print(); - } + universe.UpdateEmpireObjectVisibilities(); + // Stop and clean up Python interpreter PythonCleanup(); } Modified: trunk/FreeOrion/universe/UniverseGenerator.cpp =================================================================== --- trunk/FreeOrion/universe/UniverseGenerator.cpp 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/universe/UniverseGenerator.cpp 2014-01-26 16:17:30 UTC (rev 6735) @@ -1323,102 +1323,44 @@ treeSysListsMapIter = treeSysListsMap.begin(); } } +} - /** Set active meter current values equal to target/max meter current - * values. Useful when creating new object after applying effects. */ - void SetActiveMetersToTargetMaxCurrentValues(ObjectMap& object_map) { - std::map<MeterType, MeterType> meters; - meters[METER_POPULATION] = METER_TARGET_POPULATION; - meters[METER_INDUSTRY] = METER_TARGET_INDUSTRY; - meters[METER_RESEARCH] = METER_TARGET_RESEARCH; - meters[METER_TRADE] = METER_TARGET_TRADE; - meters[METER_CONSTRUCTION] = METER_TARGET_CONSTRUCTION; - meters[METER_FUEL] = METER_MAX_FUEL; - meters[METER_SHIELD] = METER_MAX_SHIELD; - meters[METER_STRUCTURE] = METER_MAX_STRUCTURE; - meters[METER_DEFENSE] = METER_MAX_DEFENSE; - meters[METER_TROOPS] = METER_MAX_TROOPS; +void SetActiveMetersToTargetMaxCurrentValues(ObjectMap& object_map) { + std::map<MeterType, MeterType> meters; + meters[METER_POPULATION] = METER_TARGET_POPULATION; + meters[METER_INDUSTRY] = METER_TARGET_INDUSTRY; + meters[METER_RESEARCH] = METER_TARGET_RESEARCH; + meters[METER_TRADE] = METER_TARGET_TRADE; + meters[METER_CONSTRUCTION] = METER_TARGET_CONSTRUCTION; + meters[METER_FUEL] = METER_MAX_FUEL; + meters[METER_SHIELD] = METER_MAX_SHIELD; + meters[METER_STRUCTURE] = METER_MAX_STRUCTURE; + meters[METER_DEFENSE] = METER_MAX_DEFENSE; + meters[METER_TROOPS] = METER_MAX_TROOPS; - // check for each pair of meter types. if both exist, set active - // meter current value equal to target meter current value. - for (ObjectMap::iterator<> it = object_map.begin(); it != object_map.end(); ++it) { - for (std::map<MeterType, MeterType>::const_iterator meter_it = meters.begin(); meter_it != meters.end(); ++meter_it) - if (Meter* meter = it->GetMeter(meter_it->first)) - if (Meter* targetmax_meter = it->GetMeter(meter_it->second)) - meter->SetCurrent(targetmax_meter->Current()); - } + // check for each pair of meter types. if both exist, set active + // meter current value equal to target meter current value. + for (ObjectMap::iterator<> it = object_map.begin(); it != object_map.end(); ++it) { + for (std::map<MeterType, MeterType>::const_iterator meter_it = meters.begin(); meter_it != meters.end(); ++meter_it) + if (Meter* meter = it->GetMeter(meter_it->first)) + if (Meter* targetmax_meter = it->GetMeter(meter_it->second)) + meter->SetCurrent(targetmax_meter->Current()); } +} - /** Set the population of unowned planets to a random fraction of - * their target values. */ - void SetNativePopulationValues(ObjectMap& object_map) { - - for (ObjectMap::iterator<> it = object_map.begin(); it != object_map.end(); ++it) { - Meter* meter = it->GetMeter(METER_POPULATION); - Meter* targetmax_meter = it->GetMeter(METER_TARGET_POPULATION); - // only applies to unowned planets - if (meter && targetmax_meter && it->Unowned()) { - double r = RandZeroToOne(); - double factor = (0.1<r)?r:0.1; - meter->SetCurrent(targetmax_meter->Current() * factor); - } +void SetNativePopulationValues(ObjectMap& object_map) { + for (ObjectMap::iterator<> it = object_map.begin(); it != object_map.end(); ++it) { + Meter* meter = it->GetMeter(METER_POPULATION); + Meter* targetmax_meter = it->GetMeter(METER_TARGET_POPULATION); + // only applies to unowned planets + if (meter && targetmax_meter && it->Unowned()) { + double r = RandZeroToOne(); + double factor = (0.1<r)?r:0.1; + meter->SetCurrent(targetmax_meter->Current() * factor); } } } -void CreateUniverse(int size, Shape shape, - GalaxySetupOption age, GalaxySetupOption starlane_freq, - GalaxySetupOption planet_density, GalaxySetupOption specials_freq, - GalaxySetupOption monster_freq, GalaxySetupOption native_freq, - const std::vector<SystemPosition>& positions, - const std::map<int, PlayerSetupData>& player_setup_data) -{ - Universe& universe = GetUniverse(); - std::vector<int> homeworld_planet_ids; - - Logger().debugStream() << "CreateUniverse: universe width: " << universe.UniverseWidth(); - - Logger().debugStream() << "Generating Fields"; - GenerateFields(universe, GALAXY_SETUP_MEDIUM); - Logger().debugStream() << "Generating Natives"; - GenerateNatives(universe, native_freq); - Logger().debugStream() << "Generating Space Monsters"; - GenerateSpaceMonsters(universe, monster_freq); - Logger().debugStream() << "Adding Starting Specials"; - AddStartingSpecials(universe, specials_freq); - - Logger().debugStream() << "Applying first turn effects and updating meters"; - - // Apply effects for 1st turn. - universe.ApplyAllEffectsAndUpdateMeters(); - Logger().debugStream() << "Finished applying all effects and updating meters."; - // Set active meters to targets or maxes after first meter effects application - SetActiveMetersToTargetMaxCurrentValues(universe.Objects()); - - universe.BackPropegateObjectMeters(); - Empires().BackPropegateMeters(); - - Logger().debugStream() << "Re-applying first turn meter effects and updating meters"; - - // Re-apply meter effects, so that results depending on meter values can be - // re-checked after initial setting of those meter values - universe.ApplyMeterEffectsAndUpdateMeters(); - // Re-set active meters to targets after re-application of effects - SetActiveMetersToTargetMaxCurrentValues(universe.Objects()); - // Set the population of unowned planets to a random fraction of their target values. - SetNativePopulationValues(universe.Objects()); - - universe.BackPropegateObjectMeters(); - Empires().BackPropegateMeters(); - - if (GetOptionsDB().Get<bool>("verbose-logging")) { - Logger().debugStream() << "!!!!!!!!!!!!!!!!!!! After setting active meters to targets"; - Logger().debugStream() << universe.Objects().Dump(); - } - - universe.UpdateEmpireObjectVisibilities(); -} - void AddStartingSpecials(Universe& universe, GalaxySetupOption specials_freq) { Logger().debugStream() << "AddStartingSpecials"; @@ -2030,7 +1972,7 @@ }; bool SetEmpireHomeworld(Empire* empire, int planet_id, std::string species_name) { - // set ownership of home planet + // get home planet and system, check if they exist TemporaryPtr<Planet> home_planet = GetPlanet(planet_id); TemporaryPtr<System> home_system; if (home_planet) @@ -2044,38 +1986,39 @@ << " (planet " << home_planet->ID() << ") to be home system for empire " << empire->EmpireID(); - home_planet->SetOwner(empire->EmpireID()); - empire->SetCapitalID(home_planet->ID()); - empire->AddExploredSystem(home_planet->SystemID()); - - home_planet->SetSpecies(species_name); - if (Species* species = GetSpeciesManager().GetSpecies(species_name)) { - species->AddHomeworld(home_planet->ID()); - - // set homeword's planet type to the preferred type for this species - const std::map<PlanetType, PlanetEnvironment>& spte = species->PlanetEnvironments(); - if (!spte.empty()) { - // invert map from planet type to environments to map from - // environments to type, sorted by environment - std::map<PlanetEnvironment, PlanetType> sept; - for (std::map<PlanetType, PlanetEnvironment>::const_iterator it = spte.begin(); it != spte.end(); ++it) - sept[it->second] = it->first; - // assuming enum values are ordered in increasing goodness... - PlanetType preferred_planet_type = sept.rbegin()->second; - - home_planet->SetType(preferred_planet_type); - if (preferred_planet_type == PT_ASTEROIDS) - home_planet->SetSize(SZ_ASTEROIDS); - else if (preferred_planet_type == PT_GASGIANT) - home_planet->SetSize(SZ_GASGIANT); - } - - } else { + // get species, check if it exists + Species* species = GetSpeciesManager().GetSpecies(species_name); + if (!species) { Logger().errorStream() << "UniverseGenerator::SetEmpireHomeworld: couldn't get species \"" << species_name << "\" to set with homeworld id " << home_planet->ID(); return false; } + // set homeword's planet type to the preferred type for this species + const std::map<PlanetType, PlanetEnvironment>& spte = species->PlanetEnvironments(); + if (!spte.empty()) { + // invert map from planet type to environments to map from + // environments to type, sorted by environment + std::map<PlanetEnvironment, PlanetType> sept; + for (std::map<PlanetType, PlanetEnvironment>::const_iterator it = spte.begin(); it != spte.end(); ++it) + sept[it->second] = it->first; + // assuming enum values are ordered in increasing goodness... + PlanetType preferred_planet_type = sept.rbegin()->second; + + home_planet->SetType(preferred_planet_type); + if (preferred_planet_type == PT_ASTEROIDS) + home_planet->SetSize(SZ_ASTEROIDS); + else if (preferred_planet_type == PT_GASGIANT) + home_planet->SetSize(SZ_GASGIANT); + else + home_planet->SetSize(SZ_MEDIUM); + } + + home_planet->Colonize(empire->EmpireID(), species_name, Meter::LARGE_VALUE); + species->AddHomeworld(home_planet->ID()); + empire->SetCapitalID(home_planet->ID()); + empire->AddExploredSystem(home_planet->SystemID()); + return true; } @@ -2091,14 +2034,14 @@ for (std::map<int, PlayerSetupData>::const_iterator setup_data_it = player_setup_data.begin(); setup_data_it != player_setup_data.end(); ++setup_data_it, ++player_i) { - int player_id = setup_data_it->first; + int player_id = setup_data_it->first; if (player_id == Networking::INVALID_PLAYER_ID) Logger().errorStream() << "Universe::InitEmpires player id (" << player_id << ") is invalid"; // use player ID for empire ID so that the calling code can get the // correct empire for each player ID in player_setup_data - int empire_id = player_id; - std::string player_name = setup_data_it->second.m_player_name; - GG::Clr empire_colour = setup_data_it->second.m_empire_color; + int empire_id = player_id; + std::string player_name = setup_data_it->second.m_player_name; + GG::Clr empire_colour = setup_data_it->second.m_empire_color; // validate or generate empire colour // ensure no other empire gets auto-assigned this colour automatically Modified: trunk/FreeOrion/universe/UniverseGenerator.h =================================================================== --- trunk/FreeOrion/universe/UniverseGenerator.h 2014-01-26 15:52:04 UTC (rev 6734) +++ trunk/FreeOrion/universe/UniverseGenerator.h 2014-01-26 16:17:30 UTC (rev 6735) @@ -116,6 +116,14 @@ void IrregularGalaxyPositions(std::vector<SystemPosition>& positions, unsigned int stars, double width, double height); +/** Set active meter current values equal to target/max meter current + * values. Useful when creating new object after applying effects. */ +void SetActiveMetersToTargetMaxCurrentValues(ObjectMap& object_map); + +/** Set the population of unowned planets to a random fraction of + * their target values. */ +void SetNativePopulationValues(ObjectMap& object_map); + /** Adds start-of-game specials to objects. */ void AddStartingSpecials(Universe& universe, GalaxySetupOption specials_freq); @@ -148,17 +156,4 @@ * can know which empire belongs to which player). */ void InitEmpires(const std::map<int, PlayerSetupData>& player_setup_data); -/** Generates systems and planets, assigns homeworlds and populates them - * with people, industry and bases, and places starting fleets. Uses - * predefined galaxy shapes. - * WILL BE REMOVED!!! Currently kept because the new Python universe - * generator interface is not yet able to replace this function completely */ -void CreateUniverse(int size, Shape shape, - GalaxySetupOption age, GalaxySetupOption starlane_freq, - GalaxySetupOption planet_density, GalaxySetupOption specials_freq, - GalaxySetupOption monster_freq, GalaxySetupOption native_freq, - const std::vector<SystemPosition>& positions, - const std::map<int, PlayerSetupData>& player_setup_data); - - #endif // _UniverseGenerator_h_ \ No newline at end of file |