From: <geo...@us...> - 2008-02-22 19:21:28
|
Revision: 2352 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=2352&view=rev Author: geoffthemedio Date: 2008-02-22 11:21:33 -0800 (Fri, 22 Feb 2008) Log Message: ----------- -Exposed most details of ShipDesign to Python -Exposed order to create new ShipDesigns -A few related minor changes Modified Paths: -------------- trunk/FreeOrion/AI/AIInterface.cpp trunk/FreeOrion/AI/AIInterface.h trunk/FreeOrion/AI/PythonAI.cpp trunk/FreeOrion/UI/DesignWnd.cpp trunk/FreeOrion/python/PythonEmpireWrapper.cpp trunk/FreeOrion/python/PythonUniverseWrapper.cpp trunk/FreeOrion/universe/ShipDesign.cpp trunk/FreeOrion/universe/ShipDesign.h Modified: trunk/FreeOrion/AI/AIInterface.cpp =================================================================== --- trunk/FreeOrion/AI/AIInterface.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/AI/AIInterface.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -49,13 +49,13 @@ ////////////////////////////////// namespace { // stuff used in AIInterface, but not needed to be visible outside this file - - // fleet and resource supply distribution - std::map<int, std::set<int> > s_empire_system_fleet_supply; // map from empire id to set of systems that empire can provide fleet supply to this turn - std::map<int, std::set<std::pair<int, int> > > s_empire_fleet_supply_lanes; // map from empire id to set of starlanes (stored as directed pair of start and end system ids) along which fleet supply travels for that empire - std::map<int, std::set<std::set<int> > > s_empire_resource_sharing_groups; // map from empire id to set of sets of systems that can share resources for that empire - std::map<int, std::set<std::pair<int, int> > > s_empire_resource_sharing_lanes; // map from empire id to set of starlanes (stored as directed pair of start and end system ids) along which inter-system resource sharing travels for that empire + // fleet and resource supply distribution + std::map<int, std::set<int> > s_empire_system_fleet_supply; // map from empire id to set of systems that empire can provide fleet supply to this turn + std::map<int, std::set<std::pair<int, int> > > s_empire_fleet_supply_lanes; // map from empire id to set of starlanes (stored as directed pair of start and end system ids) along which fleet supply travels for that empire + std::map<int, std::set<std::set<int> > > s_empire_resource_sharing_groups; // map from empire id to set of sets of systems that can share resources for that empire + std::map<int, std::set<std::pair<int, int> > > s_empire_resource_sharing_lanes; // map from empire id to set of starlanes (stored as directed pair of start and end system ids) along which inter-system resource sharing travels for that empire + // start of turn initialization for meters void InitMeterEstimatesAndDiscrepancies() { Universe& universe = AIClientApp::GetApp()->GetUniverse(); @@ -66,22 +66,22 @@ // between which systems resources can be exchanged (which is necessary to know before resource pools can be // updated void InitResourcePools() { - EmpireManager& manager = AIClientApp::GetApp()->Empires(); - - // determine sytems where fleets can delivery supply, and groups of systems that can exchange resources - for (EmpireManager::iterator it = manager.begin(); it != manager.end(); ++it) { - int empire_id = it->first; - Empire* empire = it->second; - - // get supplyable systems for fleets and starlanes used for fleet supply for current empire... - empire->GetSupplyableSystemsAndStarlanesUsed(s_empire_system_fleet_supply[empire_id], - s_empire_fleet_supply_lanes[empire_id]); - - // get sets of systems from and to which physical resources can be shared - empire->GetSupplySystemGroupsAndStarlanesUsed(s_empire_resource_sharing_groups[empire_id], - s_empire_resource_sharing_lanes[empire_id]); - - empire->InitResourcePools(s_empire_resource_sharing_groups[empire_id]); + EmpireManager& manager = AIClientApp::GetApp()->Empires(); + + // determine sytems where fleets can delivery supply, and groups of systems that can exchange resources + for (EmpireManager::iterator it = manager.begin(); it != manager.end(); ++it) { + int empire_id = it->first; + Empire* empire = it->second; + + // get supplyable systems for fleets and starlanes used for fleet supply for current empire... + empire->GetSupplyableSystemsAndStarlanesUsed(s_empire_system_fleet_supply[empire_id], + s_empire_fleet_supply_lanes[empire_id]); + + // get sets of systems from and to which physical resources can be shared + empire->GetSupplySystemGroupsAndStarlanesUsed(s_empire_resource_sharing_groups[empire_id], + s_empire_resource_sharing_lanes[empire_id]); + + empire->InitResourcePools(s_empire_resource_sharing_groups[empire_id]); } } } @@ -178,46 +178,46 @@ } void UpdateMeterEstimates(bool pretend_unowned_planets_owned_by_this_ai_empire) { - std::vector<Planet*> unowned_planets; - int player_id = -1; - Universe& universe = AIClientApp::GetApp()->GetUniverse(); - if (pretend_unowned_planets_owned_by_this_ai_empire) { - // add this player ownership to all planets that the player can see but which aren't currently colonized. - // this way, any effects the player knows about that would act on those planets if the player colonized them - // include those planets in their scope. This lets effects from techs the player knows alter the max - // population of planet that is displayed to the player, even if those effects have a condition that causes - // them to only act on planets the player owns (so as to not improve enemy planets if a player reseraches a - // tech that should only benefit him/herself) - player_id = AIInterface::PlayerID(); - - // get all planets the player knows about that aren't yet colonized (aren't owned by anyone). Add this - // the current player's ownership to all, while remembering which planets this is done to - std::vector<Planet*> all_planets = universe.FindObjects<Planet>(); - Universe::InhibitUniverseObjectSignals(true); - for (std::vector<Planet*>::iterator it = all_planets.begin(); it != all_planets.end(); ++it) { - Planet* planet = *it; - if (planet->Owners().empty()) { - unowned_planets.push_back(planet); - planet->AddOwner(player_id); - } - } - } - - // update meter estimates with temporary ownership - universe.UpdateMeterEstimates(); - - if (pretend_unowned_planets_owned_by_this_ai_empire) { - // remove temporary ownership added above - for (std::vector<Planet*>::iterator it = unowned_planets.begin(); it != unowned_planets.end(); ++it) - (*it)->RemoveOwner(player_id); + std::vector<Planet*> unowned_planets; + int player_id = -1; + Universe& universe = AIClientApp::GetApp()->GetUniverse(); + if (pretend_unowned_planets_owned_by_this_ai_empire) { + // add this player ownership to all planets that the player can see but which aren't currently colonized. + // this way, any effects the player knows about that would act on those planets if the player colonized them + // include those planets in their scope. This lets effects from techs the player knows alter the max + // population of planet that is displayed to the player, even if those effects have a condition that causes + // them to only act on planets the player owns (so as to not improve enemy planets if a player reseraches a + // tech that should only benefit him/herself) + player_id = AIInterface::PlayerID(); + + // get all planets the player knows about that aren't yet colonized (aren't owned by anyone). Add this + // the current player's ownership to all, while remembering which planets this is done to + std::vector<Planet*> all_planets = universe.FindObjects<Planet>(); + Universe::InhibitUniverseObjectSignals(true); + for (std::vector<Planet*>::iterator it = all_planets.begin(); it != all_planets.end(); ++it) { + Planet* planet = *it; + if (planet->Owners().empty()) { + unowned_planets.push_back(planet); + planet->AddOwner(player_id); + } + } + } + + // update meter estimates with temporary ownership + universe.UpdateMeterEstimates(); + + if (pretend_unowned_planets_owned_by_this_ai_empire) { + // remove temporary ownership added above + for (std::vector<Planet*>::iterator it = unowned_planets.begin(); it != unowned_planets.end(); ++it) + (*it)->RemoveOwner(player_id); Universe::InhibitUniverseObjectSignals(false); } } void UpdateResourcePoolsAndQueues() { - EmpireManager& manager = AIClientApp::GetApp()->Empires(); - for (EmpireManager::iterator it = manager.begin(); it != manager.end(); ++it) - it->second->UpdateResourcePools(); + EmpireManager& manager = AIClientApp::GetApp()->Empires(); + for (EmpireManager::iterator it = manager.begin(); it != manager.end(); ++it) + it->second->UpdateResourcePools(); } int IssueFleetMoveOrder(int fleet_id, int destination_id) { @@ -561,6 +561,40 @@ return 1; } + int IssueCreateShipDesignOrder(const std::string& name, const std::string& description, + const std::string& hull, + const std::vector<std::string>& external_parts, + const std::vector<std::string>& internal_parts, + const std::string& graphic, const std::string& model) + { + if (name.empty() || description.empty() || hull.empty() || graphic.empty()) { + Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder : passed an empty name, description, hull or graphic."; + return 0; + } + if (!ShipDesign::ValidDesign(hull, external_parts, internal_parts)) { + Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder : pass a hull and parts that do not make a valid ShipDesign"; + return 0; + } + + int empire_id = AIClientApp::GetApp()->EmpireID(); + int current_turn = CurrentTurn(); + + // create design from stuff chosen in UI + ShipDesign* design = new ShipDesign(name, description, empire_id, current_turn, + hull, external_parts, internal_parts, + graphic, model); + + if (!design) { + Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder failed to create a new ShipDesign object"; + return 0; + } + + int new_design_id = AIClientApp::GetApp()->GetNewDesignID(); + AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new ShipDesignOrder(empire_id, new_design_id, *design))); + + return 1; + } + void SendPlayerChatMessage(int recipient_player_id, const std::string& message_text) { if (recipient_player_id == -1) AIClientApp::GetApp()->Networking().SendMessage(GlobalChatMessage(PlayerID(), message_text)); Modified: trunk/FreeOrion/AI/AIInterface.h =================================================================== --- trunk/FreeOrion/AI/AIInterface.h 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/AI/AIInterface.h 2008-02-22 19:21:33 UTC (rev 2352) @@ -2,6 +2,7 @@ #define AI_INTERFACE #include "../universe/Universe.h" +#include "../universe/ShipDesign.h" #include <string> @@ -79,6 +80,12 @@ int IssueRequeueProductionOrder(int old_queue_index, int new_queue_index); int IssueDequeueProductionOrder(int queue_index); + int IssueCreateShipDesignOrder(const std::string& name, const std::string& description, + const std::string& hull, + const std::vector<std::string>& external_parts, + const std::vector<std::string>& internal_parts, + const std::string& graphic, const std::string& model); + void SendPlayerChatMessage(int recipient_player_id, const std::string& message_text); void DoneTurn(); ///< AI player is done submitting orders for this turn Modified: trunk/FreeOrion/AI/PythonAI.cpp =================================================================== --- trunk/FreeOrion/AI/PythonAI.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/AI/PythonAI.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -115,6 +115,7 @@ def("issueEnqueueShipProductionOrder", AIInterface::IssueEnqueueShipProductionOrder); def("issueRequeueProductionOrder", AIInterface::IssueRequeueProductionOrder); def("issueDequeueProductionOrder", AIInterface::IssueDequeueProductionOrder); + def("IssueCreateShipDesignOrder", AIInterface::IssueCreateShipDesignOrder); def("sendChatMessage", AIInterface::SendPlayerChatMessage); Modified: trunk/FreeOrion/UI/DesignWnd.cpp =================================================================== --- trunk/FreeOrion/UI/DesignWnd.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/UI/DesignWnd.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -137,11 +137,11 @@ int new_design_id = HumanClientApp::GetApp()->GetNewDesignID(); HumanClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new ShipDesignOrder(empire_id, new_design_id, *design))); - Logger().errorStream() << "Added new design: " << design->Name(); + Logger().debugStream() << "Added new design: " << design->Name(); const Universe& universe = GetUniverse(); for (Universe::ship_design_iterator it = universe.beginShipDesigns(); it != universe.endShipDesigns(); ++it) - Logger().errorStream() << "Shipdesign: " << it->second->Name(); + Logger().debugStream() << "Shipdesign: " << it->second->Name(); } void DesignWnd::HullSelected(int hull_index) { Modified: trunk/FreeOrion/python/PythonEmpireWrapper.cpp =================================================================== --- trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -164,5 +164,7 @@ .add_property("prerequisites", make_function(&Tech::Prerequisites, return_internal_reference<>())) .add_property("unlockedTechs", make_function(&Tech::UnlockedTechs, return_internal_reference<>())) ; + def("getTech", &GetTech, return_value_policy<reference_existing_object>()); + def("getTechCategories", &TechManager::CategoryNames, return_value_policy<return_by_value>()); } } \ No newline at end of file Modified: trunk/FreeOrion/python/PythonUniverseWrapper.cpp =================================================================== --- trunk/FreeOrion/python/PythonUniverseWrapper.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/python/PythonUniverseWrapper.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -19,9 +19,14 @@ const Planet* (Universe::*UniverseGetPlanet)(int) = &Universe::Object; const System* (Universe::*UniverseGetSystem)(int) = &Universe::Object; const Building* (Universe::*UniverseGetBuilding)(int) = &Universe::Object; -} + bool (*ValidDesignHullAndParts)(const std::string& hull, + const std::vector<std::string>& external_parts, + const std::vector<std::string>& internal_parts) = &ShipDesign::ValidDesign; + bool (*ValidDesignDesign)(const ShipDesign&) = &ShipDesign::ValidDesign;} + namespace FreeOrionPython { + using boost::python::def; using boost::python::class_; using boost::python::bases; using boost::python::no_init; @@ -60,7 +65,6 @@ .def("getPlanet", UniverseGetPlanet, return_value_policy<reference_existing_object>()) .def("getSystem", UniverseGetSystem, return_value_policy<reference_existing_object>()) .def("getBuilding", UniverseGetBuilding, return_value_policy<reference_existing_object>()) - .def("getSpecial", GetSpecial, return_value_policy<reference_existing_object>()) .add_property("allObjectIDs", make_function(&Universe::FindObjectIDs<UniverseObject>, return_value_policy<return_by_value>())) .add_property("systemIDs", make_function(&Universe::FindObjectIDs<System>, return_value_policy<return_by_value>())) @@ -110,9 +114,9 @@ // Ship // ////////////////// class_<Ship, bases<UniverseObject>, noncopyable>("ship", no_init) - .add_property("design", make_function(&Ship::Design, return_value_policy<reference_existing_object>())) + .add_property("design", make_function(&Ship::Design, return_value_policy<reference_existing_object>())) .add_property("fleetID", &Ship::FleetID) - .add_property("getFleet", make_function(&Ship::GetFleet, return_value_policy<reference_existing_object>())) + .add_property("getFleet", make_function(&Ship::GetFleet, return_value_policy<reference_existing_object>())) .add_property("isArmed", &Ship::IsArmed) .add_property("speed", &Ship::Speed) ; @@ -121,30 +125,56 @@ // ShipDesign // ////////////////// class_<ShipDesign, noncopyable>("shipDesign", no_init) - .add_property("name", make_function(&ShipDesign::Name, return_value_policy<copy_const_reference>())) + .add_property("id", make_function(&ShipDesign::ID, return_value_policy<return_by_value>())) + .add_property("name", make_function(&ShipDesign::Name, return_value_policy<copy_const_reference>())) + .add_property("description", make_function(&ShipDesign::Description, return_value_policy<copy_const_reference>())) + .add_property("designedByEmpireID", make_function(&ShipDesign::DesignedByEmpire, return_value_policy<return_by_value>())) + .add_property("designedOnTurn", make_function(&ShipDesign::DesignedOnTurn, return_value_policy<return_by_value>())) + .add_property("starlaneSpeed", make_function(&ShipDesign::StarlaneSpeed, return_value_policy<return_by_value>())) + .add_property("battleSpeed", make_function(&ShipDesign::BattleSpeed, return_value_policy<return_by_value>())) + .add_property("mass", make_function(&ShipDesign::Mass, return_value_policy<return_by_value>())) + .add_property("defense", make_function(&ShipDesign::Defense, return_value_policy<return_by_value>())) + .add_property("speed", make_function(&ShipDesign::Speed, return_value_policy<return_by_value>())) + .add_property("attack", make_function(&ShipDesign::Attack, return_value_policy<return_by_value>())) + .add_property("canColonize", make_function(&ShipDesign::Colonize, return_value_policy<return_by_value>())) + .add_property("cost", make_function(&ShipDesign::Cost, return_value_policy<return_by_value>())) + .add_property("buildTime", make_function(&ShipDesign::BuildTime, return_value_policy<return_by_value>())) + .add_property("hull", make_function(&ShipDesign::Hull, return_value_policy<return_by_value>())) + .add_property("externalParts", make_function(&ShipDesign::ExternalParts, return_internal_reference<>())) + .add_property("internalParts", make_function(&ShipDesign::InternalParts, return_internal_reference<>())) + .add_property("parts", make_function(&ShipDesign::Parts, return_value_policy<return_by_value>())) + //.add_property("graphic", make_function(&ShipDesign::Graphic, return_value_policy<copy_const_reference>())) + //.add_property("model", make_function(&ShipDesign::Model, return_value_policy<copy_const_reference>())) + .def("productionLocationForEmpire", &ShipDesign::ProductionLocation) ; + def("validShipDesign", ValidDesignHullAndParts); + def("validShipDesign", ValidDesignDesign); + def("getShipDesign", &GetShipDesign, return_value_policy<reference_existing_object>()); + ////////////////// // Building // ////////////////// class_<Building, bases<UniverseObject>, noncopyable>("building", no_init) - .def("getBuildingType", &Building::GetBuildingType, return_value_policy<reference_existing_object>()) + .def("getBuildingType", &Building::GetBuildingType, return_value_policy<reference_existing_object>()) .add_property("operating", &Building::Operating) - .def("getPlanet", &Building::GetPlanet, return_value_policy<reference_existing_object>()) + .def("getPlanet", &Building::GetPlanet, return_value_policy<reference_existing_object>()) ; ////////////////// // BuildingType // ////////////////// class_<BuildingType, noncopyable>("buildingType", no_init) - .add_property("name", make_function(&BuildingType::Name, return_value_policy<copy_const_reference>())) - .add_property("description", make_function(&BuildingType::Description, return_value_policy<copy_const_reference>())) + .add_property("name", make_function(&BuildingType::Name, return_value_policy<copy_const_reference>())) + .add_property("description", make_function(&BuildingType::Description, return_value_policy<copy_const_reference>())) .add_property("buildCost", &BuildingType::BuildCost) .add_property("buildTime", &BuildingType::BuildTime) .add_property("maintenanceCost", &BuildingType::MaintenanceCost) .def("captureResult", &BuildingType::GetCaptureResult) ; + def("getBuildingType", &GetBuildingType, return_value_policy<reference_existing_object>()); + //////////////////// // ResourceCenter // //////////////////// @@ -167,7 +197,7 @@ class_<Planet, bases<UniverseObject, PopCenter, ResourceCenter>, noncopyable>("planet", no_init) .add_property("size", &Planet::Size) .add_property("type", &Planet::Type) - .add_property("buildingIDs", make_function(&Planet::Buildings, return_internal_reference<>())) + .add_property("buildingIDs", make_function(&Planet::Buildings, return_internal_reference<>())) ; ////////////////// @@ -192,5 +222,6 @@ .add_property("name", make_function(&Special::Name, return_value_policy<copy_const_reference>())) .add_property("description", make_function(&Special::Description, return_value_policy<copy_const_reference>())) ; + def("getSpecial", &GetSpecial, return_value_policy<reference_existing_object>()); } } \ No newline at end of file Modified: trunk/FreeOrion/universe/ShipDesign.cpp =================================================================== --- trunk/FreeOrion/universe/ShipDesign.cpp 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/universe/ShipDesign.cpp 2008-02-22 19:21:33 UTC (rev 2352) @@ -427,6 +427,10 @@ Logger().errorStream() << "constructing an invalid ShipDesign!"; } +int ShipDesign::ID() const { + return m_id; +} + const std::string& ShipDesign::Name() const { return m_name; @@ -456,6 +460,22 @@ return m_description; } +int ShipDesign::DesignedOnTurn() const { + return m_designed_on_turn; +} + +double ShipDesign::StarlaneSpeed() const { + return GetHull()->Speed(); +} + +double ShipDesign::BattleSpeed() const { + return GetHull()->Speed(); +} + +double ShipDesign::Mass() const { + return 1.0; //TODO: this +} + const std::string& ShipDesign::Hull() const { return m_hull; } @@ -560,6 +580,10 @@ return true; } +bool ShipDesign::ValidDesign(const ShipDesign& design) { + return ValidDesign(design.m_hull, design.m_external_parts, design.m_internal_parts); +} + //// TEMPORARY double ShipDesign::Defense() const { // accumulate defense from defensive parts in design. Modified: trunk/FreeOrion/universe/ShipDesign.h =================================================================== --- trunk/FreeOrion/universe/ShipDesign.h 2008-02-22 15:46:11 UTC (rev 2351) +++ trunk/FreeOrion/universe/ShipDesign.h 2008-02-22 19:21:33 UTC (rev 2352) @@ -206,7 +206,7 @@ const std::string& Name() const; ///< returns name of design const std::string& Description() const; ///< returns description of design int DesignedByEmpire() const; ///< returns id of empire that created design - int DesginedOnTurn() const; ///< returns turn on which design was created + int DesignedOnTurn() const; ///< returns turn on which design was created double StarlaneSpeed() const; ///< returns design speed along starlanes double BattleSpeed() const; ///< returns design speed on the battle map @@ -244,6 +244,10 @@ const std::vector<std::string>& external_parts, const std::vector<std::string>& internal_parts); + ///< returns true if the \a design passed is a valid ShipDesign in terms of its hull and parts. does not check any other member variables + static bool ValidDesign(const ShipDesign& design); + + private: int m_id; |