From: <geo...@us...> - 2009-05-17 04:02:24
|
Revision: 3054 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=3054&view=rev Author: geoffthemedio Date: 2009-05-17 04:02:16 +0000 (Sun, 17 May 2009) Log Message: ----------- Fixed 2792873 - built ships have initially 0 meters Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2009-05-17 02:42:21 UTC (rev 3053) +++ trunk/FreeOrion/Empire/Empire.cpp 2009-05-17 04:02:16 UTC (rev 3054) @@ -2240,8 +2240,15 @@ // add ship Ship* ship = new Ship(m_id, m_production_queue[i].item.design_id); - ship->GetMeter(METER_FUEL)->SetCurrent(Meter::METER_MAX); // ensures ship starts with some fuel. will be clamped to max value after effects are applied to set that max value appropriately + // start with with maxed meters. current values will be clamped to max value + // after effects are applied to set that max value appropriately + ship->GetMeter(METER_FUEL)->SetCurrent(Meter::METER_MAX); + ship->GetMeter(METER_SHIELD)->SetCurrent(Meter::METER_MAX); + ship->GetMeter(METER_DETECTION)->SetCurrent(Meter::METER_MAX); + ship->GetMeter(METER_STEALTH)->SetCurrent(Meter::METER_MAX); + ship->GetMeter(METER_HEALTH)->SetCurrent(Meter::METER_MAX); + int ship_id = universe.Insert(ship); ship->Rename(NewShipName()); |
From: <geo...@us...> - 2011-09-26 18:20:28
|
Revision: 4297 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4297&view=rev Author: geoffthemedio Date: 2011-09-26 18:20:22 +0000 (Mon, 26 Sep 2011) Log Message: ----------- Fixed bug introduced in 4289 that prevented new ship designs from being added to empires, which broke the confirm new design button on the design screen. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2011-09-26 10:16:20 UTC (rev 4296) +++ trunk/FreeOrion/Empire/Empire.cpp 2011-09-26 18:20:22 UTC (rev 4297) @@ -2368,7 +2368,7 @@ const ShipDesign* ship_design = GetUniverse().GetShipDesign(ship_design_id); if (ship_design) { // design is valid, so just add the id to empire's set of ids that it knows about - if (m_ship_designs.find(ship_design_id) != m_ship_designs.end()) { + if (m_ship_designs.find(ship_design_id) == m_ship_designs.end()) { m_ship_designs.insert(ship_design_id); ShipDesignsChangedSignal(); } |
From: <geo...@us...> - 2011-10-02 07:40:02
|
Revision: 4330 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4330&view=rev Author: geoffthemedio Date: 2011-10-02 07:39:56 +0000 (Sun, 02 Oct 2011) Log Message: ----------- Made Empire consider whether a tech is researchable, a building is producible, or a ship design is producible when adding to queues, unlocking, or reporting what is available. This ensures AIs can't research / produce unwhateverable things, and that if there is an oversight in the UI code, it's less likely to be exploitable by issuing orders to do things that players shouldn't be able to do. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2011-10-02 07:36:38 UTC (rev 4329) +++ trunk/FreeOrion/Empire/Empire.cpp 2011-10-02 07:39:56 UTC (rev 4330) @@ -1180,7 +1180,7 @@ return false; // The empire needs to issue a ShipDesignOrder to add this design id to its kept designs const ShipDesign* design = GetShipDesign(ship_design_id); - if (!design) return false; + if (!design || !design->Producible()) return false; // design is kept, but still need to verify that it is buildable at this time. Part or hull tech // requirements might prevent it from being built. @@ -1274,6 +1274,9 @@ if (build_type == BT_BUILDING && !BuildingTypeAvailable(name)) return false; + const BuildingType* building_type = GetBuildingType(name); + if (!building_type || !building_type->Producible()) return false; + if (ProductionCostAndTime(build_type, name) == std::make_pair(-1.0, -1)) { // item is unknown, unavailable, or invalid. return false; @@ -1283,10 +1286,7 @@ if (!build_location) return false; if (build_type == BT_BUILDING) { - // building type must be valid... - const BuildingType* building_type = GetBuildingType(name); - if (!building_type) return false; - // ...and the specified location must be a valid production location for that building type + // specified location must be a valid production location for that building type return building_type->ProductionLocation(m_id, location); } else { @@ -1303,6 +1303,11 @@ if (build_type == BT_SHIP && !ShipDesignAvailable(design_id)) return false; + // design must be known to this empire + const ShipDesign* ship_design = GetShipDesign(design_id); + if (!ship_design || !ship_design->Producible()) return false; + + if (ProductionCostAndTime(build_type, design_id) == std::make_pair(-1.0, ShipDesign::INVALID_DESIGN_ID)) { // item is unknown, unavailable, or invalid. return false; @@ -1312,10 +1317,7 @@ if (!build_location) return false; if (build_type == BT_SHIP) { - // design must be known to this empire - const ShipDesign* ship_design = GetShipDesign(design_id); - if (!ship_design) return false; - // ...and the specified location must be a valid production location for this design + // specified location must be a valid production location for this design return ship_design->ProductionLocation(m_id, location); } else { @@ -2020,7 +2022,7 @@ void Empire::PlaceTechInQueue(const Tech* tech, int pos/* = -1*/) { - if (TechResearched(tech->Name()) || m_techs.find(tech->Name()) != m_techs.end()) + if (TechResearched(tech->Name()) || m_techs.find(tech->Name()) != m_techs.end() || !tech->Researchable()) return; ResearchQueue::iterator it = m_research_queue.find(tech); if (pos < 0 || static_cast<int>(m_research_queue.size()) <= pos) { @@ -2230,7 +2232,8 @@ const BuildingType* building_type = GetBuildingType(name); if (!building_type) Logger().errorStream() << "Empire::AddBuildingType given an invalid building type name: " << name; - m_available_building_types.insert(name); + if (building_type->Producible()) + m_available_building_types.insert(name); } void Empire::AddPartType(const std::string& name) @@ -2238,7 +2241,8 @@ const PartType* part_type = GetPartType(name); if (!part_type) Logger().errorStream() << "Empire::AddPartType given an invalid part type name: " << name; - m_available_part_types.insert(name); + if (part_type->Producible()) + m_available_part_types.insert(name); } void Empire::AddHullType(const std::string& name) @@ -2246,7 +2250,8 @@ const HullType* hull_type = GetHullType(name); if (!hull_type) Logger().errorStream() << "Empire::AddHullType given an invalid hull type name: " << name; - m_available_hull_types.insert(name); + if (hull_type->Producible()) + m_available_hull_types.insert(name); } void Empire::AddExploredSystem(int ID) @@ -2281,7 +2286,7 @@ * retain as one of it's ship designs, which are those displayed in the GUI * list of available designs for human players, and */ const ShipDesign* ship_design = GetUniverse().GetShipDesign(ship_design_id); - if (ship_design) { + if (ship_design) { // don't check if design is producible; adding a ship design is useful for more than just producing it // design is valid, so just add the id to empire's set of ids that it knows about if (m_ship_designs.find(ship_design_id) == m_ship_designs.end()) { m_ship_designs.insert(ship_design_id); |
From: <geo...@us...> - 2011-10-02 08:49:17
|
Revision: 4331 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4331&view=rev Author: geoffthemedio Date: 2011-10-02 08:49:11 +0000 (Sun, 02 Oct 2011) Log Message: ----------- Fixed a potential crash related to a recent commit when a building script fails to parse. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2011-10-02 07:39:56 UTC (rev 4330) +++ trunk/FreeOrion/Empire/Empire.cpp 2011-10-02 08:49:11 UTC (rev 4331) @@ -2230,8 +2230,10 @@ void Empire::AddBuildingType(const std::string& name) { const BuildingType* building_type = GetBuildingType(name); - if (!building_type) + if (!building_type) { Logger().errorStream() << "Empire::AddBuildingType given an invalid building type name: " << name; + return; + } if (building_type->Producible()) m_available_building_types.insert(name); } @@ -2239,8 +2241,10 @@ void Empire::AddPartType(const std::string& name) { const PartType* part_type = GetPartType(name); - if (!part_type) + if (!part_type) { Logger().errorStream() << "Empire::AddPartType given an invalid part type name: " << name; + return; + } if (part_type->Producible()) m_available_part_types.insert(name); } @@ -2248,8 +2252,10 @@ void Empire::AddHullType(const std::string& name) { const HullType* hull_type = GetHullType(name); - if (!hull_type) + if (!hull_type) { Logger().errorStream() << "Empire::AddHullType given an invalid hull type name: " << name; + return; + } if (hull_type->Producible()) m_available_hull_types.insert(name); } |
From: <geo...@us...> - 2011-10-20 07:19:38
|
Revision: 4422 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4422&view=rev Author: geoffthemedio Date: 2011-10-20 07:19:32 +0000 (Thu, 20 Oct 2011) Log Message: ----------- -Added SanitizeResearchQueue at file scope in Empire.cpp, which repeatedly loops over the research queue to remove an invalid techs from it, before proceeding with CheckResearchProgress, in order to prevent crashes when invalid techs are present, such as occurs when techs.txt changes. This is probably not the most efficient way to scan over the queue, but it seems functional for now. -Grooming Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2011-10-20 05:08:09 UTC (rev 4421) +++ trunk/FreeOrion/Empire/Empire.cpp 2011-10-20 07:19:32 UTC (rev 4422) @@ -261,39 +261,25 @@ {} bool ResearchQueue::InQueue(const Tech* tech) const -{ - return find(tech) != end(); -} +{ return find(tech) != end(); } int ResearchQueue::ProjectsInProgress() const -{ - return m_projects_in_progress; -} +{ return m_projects_in_progress; } double ResearchQueue::TotalRPsSpent() const -{ - return m_total_RPs_spent; -} +{ return m_total_RPs_spent; } bool ResearchQueue::empty() const -{ - return !m_queue.size(); -} +{ return !m_queue.size(); } unsigned int ResearchQueue::size() const -{ - return m_queue.size(); -} +{ return m_queue.size(); } ResearchQueue::const_iterator ResearchQueue::begin() const -{ - return m_queue.begin(); -} +{ return m_queue.begin(); } ResearchQueue::const_iterator ResearchQueue::end() const -{ - return m_queue.end(); -} +{ return m_queue.end(); } ResearchQueue::const_iterator ResearchQueue::find(const Tech* tech) const { @@ -409,14 +395,10 @@ } void ResearchQueue::push_back(const Tech* tech) -{ - m_queue.push_back(Element(tech, 0.0, -1)); -} +{ m_queue.push_back(Element(tech, 0.0, -1)); } void ResearchQueue::insert(iterator it, const Tech* tech) -{ - m_queue.insert(it, Element(tech, 0.0, -1)); -} +{ m_queue.insert(it, Element(tech, 0.0, -1)); } void ResearchQueue::erase(iterator it) { @@ -434,14 +416,10 @@ } ResearchQueue::iterator ResearchQueue::begin() -{ - return m_queue.begin(); -} +{ return m_queue.begin(); } ResearchQueue::iterator ResearchQueue::end() -{ - return m_queue.end(); -} +{ return m_queue.end(); } ResearchQueue::iterator ResearchQueue::UnderfundedProject() { @@ -2412,8 +2390,31 @@ m_sitrep_entries.clear(); } +namespace { + // remove nonexistant / invalid techs from queue + void SanitizeResearchQueue(ResearchQueue& queue) { + bool done = false; + while (!done) { + ResearchQueue::iterator it = queue.begin(); + while (true) { + if (it == queue.end()) { + done = true; // got all the way through the queue without finding an invalid tech + break; + } else if (!it->tech) { + queue.erase(it); // remove invalid tech, end inner loop without marking as finished + break; + } else { + ++it; // check next element + } + } + } + } +} + void Empire::CheckResearchProgress() { + SanitizeResearchQueue(m_research_queue); + // following commented line should be redundant, as previous call to UpdateResourcePools should have generated necessary info // m_research_queue.Update(this, m_resource_pools[RE_RESEARCH]->TotalAvailable(), m_research_progress); std::vector<const Tech*> to_erase; |
From: <geo...@us...> - 2012-01-06 07:47:36
|
Revision: 4573 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4573&view=rev Author: geoffthemedio Date: 2012-01-06 07:47:30 +0000 (Fri, 06 Jan 2012) Log Message: ----------- Fixed broken validation test in Empire::SetTechResearchProgress that was preventing it and the related effect from working. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-01-06 07:46:49 UTC (rev 4572) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-01-06 07:47:30 UTC (rev 4573) @@ -1970,7 +1970,7 @@ void Empire::SetTechResearchProgress(const std::string& name, double progress) { const Tech* tech = GetTech(name); - if (tech) { + if (!tech) { Logger().errorStream() << "Empire::SetTechResearchProgress no such tech as: " << name; return; } |
From: <geo...@us...> - 2012-01-24 03:26:20
|
Revision: 4609 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4609&view=rev Author: geoffthemedio Date: 2012-01-24 03:26:14 +0000 (Tue, 24 Jan 2012) Log Message: ----------- Added timer to production queue simulation to abort after 0.1 seconds, preventing extremely long turn times if lots of things are enqueued (possibly by AIs). Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-01-23 11:32:19 UTC (rev 4608) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-01-24 03:26:14 UTC (rev 4609) @@ -718,9 +718,9 @@ int turns = 1; // to keep track of how man turn-iterations simulation takes to finish items const int TOO_MANY_TURNS = 500; // stop counting turns to completion after this long, to prevent seemingly endless loops + const double TOO_LONG_TIME = 0.1; // max time in ms to spend simulating queue - // remove from simulated queue any items that can't be built due to not // meeting their location conditions might be better to re-check // buildability each turn, but this would require creating a simulated @@ -761,7 +761,8 @@ // cycle through items on queue, adding up their allotted PP until each is // finished and removed from queue until everything on queue has been // finished, in order to calculate expected completion times - while (!sim_queue.empty() && turns < TOO_MANY_TURNS) { + boost::timer sim_queue_timer; + while (!sim_queue.empty() && turns < TOO_MANY_TURNS && sim_queue_timer.elapsed() < TOO_LONG_TIME) { std::map<std::set<int>, double> allocated_pp; int projects_in_progress = 0; @@ -814,8 +815,8 @@ } ++turns; } // loop while (!sim_queue.empty() && turns < TOO_MANY_TURNS) + //Logger().debugStream() << "ProductionQueue::Update queue sim time: " << sim_queue_timer.elapsed() * 1000.0; - // mark rest of items on simulated queue (if any) as never to be finished for (unsigned int i = 0; i < sim_queue.size(); ++i) { if (sim_queue[i].remaining == m_queue[sim_queue_original_indices[i]].remaining) |
From: <geo...@us...> - 2012-01-25 00:11:16
|
Revision: 4613 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4613&view=rev Author: geoffthemedio Date: 2012-01-25 00:11:09 +0000 (Wed, 25 Jan 2012) Log Message: ----------- Limited production queue size to 100 items. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-01-24 23:52:03 UTC (rev 4612) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-01-25 00:11:09 UTC (rev 4613) @@ -1983,6 +1983,9 @@ if (!BuildableItem(build_type, name, location)) Logger().debugStream() << "Empire::PlaceBuildInQueue() : Placed a non-buildable item in queue..."; + if (m_production_queue.size() >= 100) + return; + ProductionQueue::Element build(build_type, name, number, number, location); if (pos < 0 || static_cast<int>(m_production_queue.size()) <= pos) { m_production_queue.push_back(build); @@ -1998,6 +2001,9 @@ if (!BuildableItem(build_type, design_id, location)) Logger().debugStream() << "Empire::PlaceBuildInQueue() : Placed a non-buildable item in queue..."; + if (m_production_queue.size() >= 100) + return; + ProductionQueue::Element build(build_type, design_id, number, number, location); if (pos < 0 || static_cast<int>(m_production_queue.size()) <= pos) { m_production_queue.push_back(build); |
From: <geo...@us...> - 2012-03-08 06:10:09
|
Revision: 4696 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4696&view=rev Author: geoffthemedio Date: 2012-03-08 06:10:03 +0000 (Thu, 08 Mar 2012) Log Message: ----------- Fixed crash in Empire::AddTech when the indicated tech did not exist. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-03-08 05:30:45 UTC (rev 4695) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-03-08 06:10:03 UTC (rev 4696) @@ -2093,10 +2093,14 @@ } void Empire::AddTech(const std::string& name) { + m_techs.insert(name); + const Tech* tech = GetTech(name); - if (!tech) - Logger().errorStream() << "Empire::AddTech given and invalid tech: " << name;; - m_techs.insert(name); + if (!tech) { + Logger().errorStream() << "Empire::AddTech given and invalid tech: " << name; + return; + } + const std::vector<ItemSpec>& unlocked_items = tech->UnlockedItems(); for (unsigned int i = 0; i < unlocked_items.size(); ++i) UnlockItem(unlocked_items[i]); // potential infinite if a tech (in)directly unlocks itself? |
From: <geo...@us...> - 2012-03-29 05:18:49
|
Revision: 4758 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=4758&view=rev Author: geoffthemedio Date: 2012-03-29 05:18:43 +0000 (Thu, 29 Mar 2012) Log Message: ----------- Attempting to fix reported issue where empires could propagate fleet supply out of systems even though an enemy / monster ship was in the system and should have blockaded it. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-03-28 14:00:50 UTC (rev 4757) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-03-29 05:18:43 UTC (rev 4758) @@ -964,6 +964,7 @@ const Alignment& alignment = *it; m_meters[alignment.Name()]; } + m_meters["METER_DETECTION"]; } Empire::~Empire() @@ -1410,8 +1411,16 @@ m_fleet_supplyable_system_ids.clear(); m_fleet_supply_starlane_traversals.clear(); - // store range of all systems before propegation of supply in working map used to propegate that range to other systems. - std::map<int, int> propegating_fleet_supply_ranges = m_fleet_supply_system_ranges; + // store range of all systems before propegation of supply in working map + // used to propegate that range to other systems. exclude systems that are + // supply obstructed + std::map<int, int> propegating_fleet_supply_ranges; + for (std::map<int, int>::const_iterator it = m_fleet_supply_system_ranges.begin(); + it != m_fleet_supply_system_ranges.end(); ++it) + { + if (m_supply_unobstructed_systems.find(it->first) != m_supply_unobstructed_systems.end()) + propegating_fleet_supply_ranges.insert(*it); + } // insert all systems that produce supply on their own into a list of systems to process std::list<int> propegating_systems_list; // working list of systems to propegate supply from @@ -1432,7 +1441,8 @@ continue; } - // can propegate further, if adjacent systems have smaller supply range than one less than this system's range + // can propegate further, if adjacent systems have smaller supply range + // than one less than this system's range std::map<int, std::set<int> >::const_iterator system_it = starlanes.find(cur_sys_id); if (system_it == starlanes.end()) { // no starlanes out of this system @@ -1441,10 +1451,13 @@ } const std::set<int>& starlane_ends = system_it->second; - for (std::set<int>::const_iterator lane_it = starlane_ends.begin(); lane_it != starlane_ends.end(); ++lane_it) { + for (std::set<int>::const_iterator lane_it = starlane_ends.begin(); + lane_it != starlane_ends.end(); ++lane_it) + { int lane_end_sys_id = *lane_it; - if (m_supply_unobstructed_systems.find(lane_end_sys_id) == m_supply_unobstructed_systems.end()) continue; // can't propegate here + if (m_supply_unobstructed_systems.find(lane_end_sys_id) == m_supply_unobstructed_systems.end()) + continue; // can't propegate here // compare next system's supply range to this system's supply range. propegate if necessary. std::map<int, int>::const_iterator lane_end_sys_it = propegating_fleet_supply_ranges.find(lane_end_sys_id); @@ -1469,8 +1482,11 @@ } // convert supply ranges info into output set of supplyable systems - for (std::map<int, int>::const_iterator it = propegating_fleet_supply_ranges.begin(); it != propegating_fleet_supply_ranges.end(); ++it) + for (std::map<int, int>::const_iterator it = propegating_fleet_supply_ranges.begin(); + it != propegating_fleet_supply_ranges.end(); ++it) + { m_fleet_supplyable_system_ids.insert(it->first); + } } void Empire::UpdateResourceSupply() |
From: <geo...@us...> - 2012-08-07 01:06:27
|
Revision: 5108 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5108&view=rev Author: geoffthemedio Date: 2012-08-07 01:06:21 +0000 (Tue, 07 Aug 2012) Log Message: ----------- Fixed potential crash while propagating supply if there was no detection in a system. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-08-06 22:35:42 UTC (rev 5107) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-08-07 01:06:21 UTC (rev 5108) @@ -1441,12 +1441,16 @@ int cur_sys_id = *sys_list_it; int cur_sys_range = propegating_supply_ranges[cur_sys_id]; // range away from this system that supplies can be transported + // any unobstructed system can share resources within itself + supply_groups_map[cur_sys_id].insert(cur_sys_id); + if (cur_sys_range <= 0) { // can't propegate supply out a system that has no range ++sys_list_it; continue; } + // any system with nonzero fleet supply range can provide fleet supply m_fleet_supplyable_system_ids.insert(cur_sys_id); // can propegate further, if adjacent systems have smaller supply range @@ -1506,23 +1510,20 @@ // connected components of an undirected graph, where the node // adjacency are the directly-connected systems determined above. - // note: using fleet supplyable system ids as a list of all systems where - // resources could be exchanged - // create graph boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> graph; // boost expects vertex labels to range from 0 to num vertices - 1, so need // to map from system id to graph id and back when accessing vertices std::vector<int> graph_id_to_sys_id; - graph_id_to_sys_id.reserve(m_fleet_supplyable_system_ids.size()); + graph_id_to_sys_id.reserve(supply_groups_map.size()); std::map<int, int> sys_id_to_graph_id; int graph_id = 0; - for (std::set<int>::const_iterator sys_it = m_fleet_supplyable_system_ids.begin(); - sys_it != m_fleet_supplyable_system_ids.end(); ++sys_it, ++graph_id) + for (std::map<int, std::set<int> >::const_iterator sys_it = supply_groups_map.begin(); + sys_it != supply_groups_map.end(); ++sys_it, ++graph_id) { - int sys_id = *sys_it; + int sys_id = sys_it->first; //const UniverseObject* sys = GetUniverse().Object(sys_id); //std::string name = sys->Name(); //Logger().debugStream() << "supply-exchanging system: " << name; |
From: <geo...@us...> - 2012-08-28 05:56:04
|
Revision: 5180 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5180&view=rev Author: geoffthemedio Date: 2012-08-28 05:55:57 +0000 (Tue, 28 Aug 2012) Log Message: ----------- Changes exception throws to debug / error output log entries and early abort when moving items on or removing items from queues. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-08-27 22:57:37 UTC (rev 5179) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-08-28 05:55:57 UTC (rev 5180) @@ -1884,7 +1884,12 @@ --new_index; if (index < 0 || static_cast<int>(m_production_queue.size()) <= index || new_index < 0 || static_cast<int>(m_production_queue.size()) <= new_index) - throw std::runtime_error("Empire::MoveBuildWithinQueue() : Attempted to move a production queue item to or from an invalid index."); + { + Logger().debugStream() << "Empire::MoveBuildWithinQueue index: " << index << " new index: " + << new_index << " queue size: " << m_production_queue.size(); + Logger().errorStream() << "Attempted to move a production queue item to or from an invalid index."; + return; + } ProductionQueue::Element build = m_production_queue[index]; double status = m_production_progress[index]; m_production_queue.erase(index); @@ -1895,8 +1900,11 @@ } void Empire::RemoveBuildFromQueue(int index) { - if (index < 0 || static_cast<int>(m_production_queue.size()) <= index) - throw std::runtime_error("Empire::RemoveBuildFromQueue() : Attempted to delete a production queue item with an invalid index."); + if (index < 0 || static_cast<int>(m_production_queue.size()) <= index) { + Logger().debugStream() << "Empire::RemoveBuildFromQueue index: " << index << " queue size: " << m_production_queue.size(); + Logger().errorStream() << "Attempted to delete a production queue item with an invalid index."; + return; + } m_production_queue.erase(index); m_production_progress.erase(m_production_progress.begin() + index); m_production_queue.Update(this, m_resource_pools, m_production_progress); |
From: <geo...@us...> - 2012-10-16 08:54:58
|
Revision: 5305 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5305&view=rev Author: geoffthemedio Date: 2012-10-16 08:54:51 +0000 (Tue, 16 Oct 2012) Log Message: ----------- Production and research queue simulation optimization by Dilvish. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-10-16 07:16:05 UTC (rev 5304) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-10-16 08:54:51 UTC (rev 5305) @@ -26,8 +26,16 @@ #include <boost/graph/adjacency_list.hpp> #include <boost/graph/connected_components.hpp> #include <boost/timer.hpp> +#include "boost/date_time/posix_time/posix_time.hpp" +#undef ORIG_RES_SIMULATOR +#define DP_RES_QUEUE_SIMULATOR +#undef ORIG_SIMULATOR +#define DP_QUEUE_SIMULATOR +#undef COMPARE_SIMS + + namespace { const double EPSILON = 1.0e-5; @@ -122,7 +130,7 @@ // get resource sharing group and amount of resource available to build this item const std::set<int>& group = queue_element_resource_sharing_object_groups[i]; if (group.empty()) { - Logger().debugStream() << "resource sharing group for queue element is empty. no allocating any resources to element"; + Logger().debugStream() << "resource sharing group for queue element is empty. not allocating any resources to element"; queue_element.allocated_pp = 0.0; continue; } @@ -304,78 +312,250 @@ const int TOO_MANY_TURNS = 500; // stop counting turns to completion after this long, to prevent seemingly endless loops - if (EPSILON < RPs) { - // simulate future turns in order to determine when the techs in the queue will be finished - int turns = 1; - QueueType sim_queue = m_queue; - std::map<std::string, double> sim_research_progress = research_progress; + // initialize status of everything to never getting done + for (unsigned int i = 0; i < m_queue.size(); ++i) + m_queue[i].turns_left = -1; - std::map<std::string, int> simulation_results; - // initialize simulation_results with -1 for all techs, so that any techs that aren't - // finished in simulation by turn TOO_MANY_TURNS will be left marked as never to be finished - for (unsigned int i = 0; i < sim_queue.size(); ++i) - simulation_results[m_queue[i].name] = -1; + if ( RPs <= EPSILON ) { + ResearchQueueChangedSignal(); + return; // nothing more to do if not enough RP... + } - while (!sim_queue.empty() && turns < TOO_MANY_TURNS) { - double total_RPs_spent = 0.0; - int projects_in_progress = 0; - SetTechQueueElementSpending(RPs, sim_research_progress, sim_tech_status_map, sim_queue, total_RPs_spent, projects_in_progress); - QueueType::iterator sim_q_it = sim_queue.begin(); - while (sim_q_it != sim_queue.end()) { - const std::string& name = sim_q_it->name; - const Tech* tech = GetTech(name); - if (!tech) { - Logger().errorStream() << "ResearchQueue::Update found null tech on future simulated research queue. skipping."; - ++sim_q_it; - continue; +#ifdef DP_RES_QUEUE_SIMULATOR + boost::posix_time::ptime dp_time_start; + boost::posix_time::ptime dp_time_end; +#ifdef ORIG_RES_SIMULATOR + long dp_time; +#endif + + // "Dynamic Programming" version of research queue simulator -- copy the queue simulator containers + // perform dynamic programming calculation of completion times, then after regular simulation is done compare results (if both enabled) + + //record original order & progress + // will take advantage of fact that sets (& map keys) are by default kept in sorted order lowest to highest + std::map<std::string, double> dp_prog = research_progress; + std::map< std::string, int > origQueueOrder; + std::map<int, double> dpsim_research_progress; + for (unsigned int i = 0; i < m_queue.size(); ++i) { + std::string tname = m_queue[i].name; + origQueueOrder[ tname ] = i; + dpsim_research_progress[i] = dp_prog[ tname ]; + } + + std::map<std::string, TechStatus> dpsim_tech_status_map = sim_tech_status_map; + + // initialize simulation_results with -1 for all techs, so that any techs that aren't + // finished in simulation by turn TOO_MANY_TURNS will be left marked as never to be finished + std::vector<int> dpsimulation_results(m_queue.size(), -1); + + const int DP_TURNS = TOO_MANY_TURNS; // track up to this many turns +#ifdef ORIG_RES_SIMULATOR + dp_time_start = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); +#endif + std::map<std::string, std::set<std::string> > waitingForPrereqs; + std::set<int> dpResearchableTechs; + + for (unsigned int i = 0; i < m_queue.size(); ++i) { + std::string techname = m_queue[i].name; + const Tech* tech = GetTech( techname ); + if ( dpsim_tech_status_map[ techname ] == TS_RESEARCHABLE ) { + dpResearchableTechs.insert(i); + } else if ( dpsim_tech_status_map[ techname ] == TS_UNRESEARCHABLE ) { + std::set<std::string> thesePrereqs = tech->Prerequisites(); + for (std::set<std::string>::iterator ptech_it = thesePrereqs.begin(); ptech_it != thesePrereqs.end(); ++ptech_it){ + if (dpsim_tech_status_map[ *ptech_it ] == TS_COMPLETE ) { + thesePrereqs.erase( ptech_it ); } - double& tech_progress = sim_research_progress[name]; - tech_progress += sim_q_it->allocated_rp; - if (tech->ResearchCost() - EPSILON <= tech_progress) { - sim_tech_status_map[name] = TS_COMPLETE; - sim_q_it->turns_left = simulation_results[name]; - simulation_results[name] = turns; - sim_q_it = sim_queue.erase(sim_q_it); - } else { - ++sim_q_it; + } + waitingForPrereqs[ techname ] = thesePrereqs; + } + } + + int dpturns = 0; + //ppStillAvailable[turn-1] gives the RP still available in this resource pool at turn "turn" + std::vector<double> rpStillAvailable(DP_TURNS, RPs ); // initialize to the full RP allocation for every turn + + while ((dpturns < DP_TURNS ) && !(dpResearchableTechs.empty() ) ) {// if we haven't used up our turns and still have techs to process + ++dpturns; + std::map<int, bool> alreadyProcessed; + std::set<int>::iterator curTechIt; + for (curTechIt= dpResearchableTechs.begin(); curTechIt!=dpResearchableTechs.end(); ++curTechIt) { + alreadyProcessed[ *curTechIt ] = false; + } + curTechIt = dpResearchableTechs.begin(); + while ((rpStillAvailable[dpturns-1]> EPSILON)) { // try to use up this turns RPs + if ( curTechIt==dpResearchableTechs.end() ) { + break; //will be wasting some RP this turn + } + int curTech = *curTechIt; + if ( alreadyProcessed[curTech ] ) { + ++curTechIt; + continue; + } + alreadyProcessed[curTech] = true; + const std::string& tech_name = m_queue[curTech].name; + const Tech* tech = GetTech(tech_name); + double progress = dpsim_research_progress[curTech]; + double RPs_needed = tech->ResearchCost() - progress; + double RPs_per_turn_limit = tech->ResearchCost() / std::max(tech->ResearchTime(), 1); + double RPs_to_spend = std::min( std::min(RPs_needed, RPs_per_turn_limit), rpStillAvailable[dpturns-1] ); + progress += RPs_to_spend; + dpsim_research_progress[curTech] = progress; + rpStillAvailable[dpturns-1] -= RPs_to_spend; + std::set<int>::iterator nextResTechIt = curTechIt; + int nextResTechIdx; + if ( ++nextResTechIt == dpResearchableTechs.end() ) { + nextResTechIdx = m_queue.size()+1; + } else { + nextResTechIdx = *(nextResTechIt); + } + if (tech->ResearchCost() - EPSILON <= progress) { + dpsim_tech_status_map[tech_name] = TS_COMPLETE; + dpsimulation_results[curTech] = dpturns; +#ifndef ORIG_RES_SIMULATOR + m_queue[curTech].turns_left = dpturns; +#endif + dpResearchableTechs.erase(curTechIt); + std::set<std::string> unlockedTechs= tech->UnlockedTechs(); + for (std::set<std::string>::iterator utechIt = unlockedTechs.begin(); utechIt!=unlockedTechs.end(); ++utechIt) { + std::string utechName = *utechIt; + std::map<std::string,std::set<std::string> >::iterator prereqTechIt = waitingForPrereqs.find(utechName); + if (prereqTechIt != waitingForPrereqs.end() ){ + std::set<std::string> &thesePrereqs = prereqTechIt->second; + std::set<std::string>::iterator justFinishedIt = thesePrereqs.find( tech_name ); + if (justFinishedIt != thesePrereqs.end() ) { //should always find it + thesePrereqs.erase( justFinishedIt ); + if ( thesePrereqs.empty() ) { // tech now fully unlocked + int thisTechIdx = origQueueOrder[utechName]; + dpResearchableTechs.insert(thisTechIdx); + waitingForPrereqs.erase( prereqTechIt ); + alreadyProcessed[ thisTechIdx ] = true;//doesn't get any allocation on current turn + if (thisTechIdx < nextResTechIdx ) { + nextResTechIdx = thisTechIdx; + } + } + } else { //couldnt find tech_name in prereqs list + Logger().debugStream() << "ResearchQueue::Update tech unlocking problem:"<< tech_name << "thought it was a prereq for " << utechName << "but the latter disagreed"; + } + } //else { //tech_name thinks itself a prereq for ytechName, but utechName not in prereqs -- not a problem so long as utechName not in our queue at all + // Logger().debugStream() << "ResearchQueue::Update tech unlocking problem:"<< tech_name << "thought it was a prereq for " << utechName << "but the latter disagreed"; + //} } + }// if (tech->ResearchCost() - EPSILON <= progress) + curTechIt = dpResearchableTechs.find(nextResTechIdx); + }//while ((rpStillAvailable[dpturns-1]> EPSILON)) + +#ifdef ORIG_RES_SIMULATOR + dp_time_end = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); + dp_time = (dp_time_end - dp_time_start).total_nanoseconds(); + dp_time = dp_time; // just to suppresss the compiler warning of unused var if the comparisons are not being done below. +#endif + //dp_time = dpsim_queue_timer.elapsed() * 1000; + // Logger().debugStream() << "ProductionQueue::Update queue dynamic programming sim time: " << dpsim_queue_timer.elapsed() * 1000.0; + } // while ((dpturns < DP_TURNS ) && !(dpResearchableTechs.empty() ) ) +#endif //DP_RES_QUEUE_SIMULATOR + +#ifdef ORIG_RES_SIMULATOR +#ifdef DP_RES_QUEUE_SIMULATOR + boost::posix_time::ptime orig_time_start; + boost::posix_time::ptime orig_time_end; + long orig_time; + orig_time_start = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); +#endif + // simulate future turns in order to determine when the techs in the queue will be finished + int turns = 1; + QueueType sim_queue = m_queue; + std::map<std::string, double> sim_research_progress = research_progress; + + std::map<std::string, int> simulation_results; + // initialize simulation_results with -1 for all techs, so that any techs that aren't + // finished in simulation by turn TOO_MANY_TURNS will be left marked as never to be finished + for (unsigned int i = 0; i < sim_queue.size(); ++i) + simulation_results[m_queue[i].name] = -1; + + while (!sim_queue.empty() && turns < TOO_MANY_TURNS) { + double total_RPs_spent = 0.0; + int projects_in_progress = 0; + SetTechQueueElementSpending(RPs, sim_research_progress, sim_tech_status_map, sim_queue, total_RPs_spent, projects_in_progress); + QueueType::iterator sim_q_it = sim_queue.begin(); + while (sim_q_it != sim_queue.end()) { + const std::string& name = sim_q_it->name; + const Tech* tech = GetTech(name); + if (!tech) { + Logger().errorStream() << "ResearchQueue::Update found null tech on future simulated research queue. skipping."; + ++sim_q_it; + continue; } + double& tech_progress = sim_research_progress[name]; + tech_progress += sim_q_it->allocated_rp; + if (tech->ResearchCost() - EPSILON <= tech_progress) { + sim_tech_status_map[name] = TS_COMPLETE; + sim_q_it->turns_left = simulation_results[name]; + simulation_results[name] = turns; + sim_q_it = sim_queue.erase(sim_q_it); + } else { + ++sim_q_it; + } + } - // update simulated status of techs: some may be not researchable that were previously not. - // only need to check techs that are actually on the queue, as these are the only ones - // that might now be researched - for (unsigned int i = 0; i < sim_queue.size(); ++i) { - const std::string& tech_name = sim_queue[i].name; - const Tech* tech = GetTech(tech_name); - if (!tech) continue; // already output error message above - // if tech is currently not researchable, this is because one or more of its prereqs is not researched - if (sim_tech_status_map[tech_name] == TS_UNRESEARCHABLE) { - const std::set<std::string>& prereqs = tech->Prerequisites(); - // find if any prereqs are presently not researched. if all prereqs are researched, this tech should be researchable - bool has_not_complete_prereq = false; - for (std::set<std::string>::const_iterator it = prereqs.begin(); it != prereqs.end(); ++it) { - if (sim_tech_status_map[*it] != TS_COMPLETE) { - has_not_complete_prereq = true; - break; - } + // update simulated status of techs: some may be not researchable that were previously not. + // only need to check techs that are actually on the queue, as these are the only ones + // that might now be researched + for (unsigned int i = 0; i < sim_queue.size(); ++i) { + const std::string& tech_name = sim_queue[i].name; + const Tech* tech = GetTech(tech_name); + if (!tech) continue; // already output error message above + // if tech is currently not researchable, this is because one or more of its prereqs is not researched + if (sim_tech_status_map[tech_name] == TS_UNRESEARCHABLE) { + const std::set<std::string>& prereqs = tech->Prerequisites(); + // find if any prereqs are presently not researched. if all prereqs are researched, this tech should be researchable + bool has_not_complete_prereq = false; + for (std::set<std::string>::const_iterator it = prereqs.begin(); it != prereqs.end(); ++it) { + if (sim_tech_status_map[*it] != TS_COMPLETE) { + has_not_complete_prereq = true; + break; } - if (!has_not_complete_prereq) { - // all prereqs were complete! this tech is researchable! - sim_tech_status_map[tech_name] = TS_RESEARCHABLE; - } } + if (!has_not_complete_prereq) { + // all prereqs were complete! this tech is researchable! + sim_tech_status_map[tech_name] = TS_RESEARCHABLE; + } } - ++turns; } - // return results - for (unsigned int i = 0; i < m_queue.size(); ++i) - m_queue[i].turns_left = simulation_results[m_queue[i].name]; + ++turns; + } + // return results + for (unsigned int i = 0; i < m_queue.size(); ++i) + m_queue[i].turns_left = simulation_results[m_queue[i].name]; + +#ifdef DP_RES_QUEUE_SIMULATOR // if both simulations were done, compare results +orig_time_end = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); +orig_time = (orig_time_end - orig_time_start).total_nanoseconds(); +orig_time = orig_time; // just to suppresss the compiler warning of unused var if the comparisons are not being done below. - } else { - // since there are so few RPs, indicate that the number of turns left is indeterminate by providing a number < 0 - for (unsigned int i = 0; i < m_queue.size(); ++i) - m_queue[i].turns_left = -1; +#ifdef COMPARE_SIMS + bool sameResults = true; + for (unsigned int i = 0; i< m_queue.size(); ++i ) { + if (m_queue[i].turns_left != dpsimulation_results[i]) { + sameResults = false; + break; + } } + if (sameResults ) { + Logger().debugStream() << "ResearchQueue::Update orig sim and dp_sim gave same results"; + Logger().debugStream() << "ResearchQueue::Update orig sim time: " << orig_time*1e-3 << " , dp sim time: " << dp_time*1.0e-3 << " micro sec"; + } else { + Logger().debugStream() << "ResearchQueue::Update orig sim and dp_sim gave different results"; + Logger().debugStream() << "ResearchQueue::Update orig sim time: " << orig_time*1e-3 << " , dp sim time: " << dp_time*1.0e-3 << " micro sec"; + for (unsigned int i = 0; i< m_queue.size(); ++i ) { + Logger().debugStream() << "ResearchQueue::Update Queue Item: " << m_queue[i].name; + Logger().debugStream() << "ResearchQueue::Update orig sim gave next: " << m_queue[i].turns_left; + Logger().debugStream() << "ResearchQueue::Update dp sim gave next: " << dpsimulation_results[i]; + } + } +#endif // COMPARE_SIMS +#endif // DP_RES_QUEUE_SIMULATOR +#endif //ORIG_RES_SIMULATOR ResearchQueueChangedSignal(); } @@ -678,7 +858,6 @@ sim_queue_original_indices[i] = i; - int turns = 1; // to keep track of how man turn-iterations simulation takes to finish items const int TOO_MANY_TURNS = 500; // stop counting turns to completion after this long, to prevent seemingly endless loops const double TOO_LONG_TIME = 0.1; // max time in ms to spend simulating queue @@ -719,12 +898,151 @@ } +#ifdef DP_QUEUE_SIMULATOR + boost::posix_time::ptime dp_time_start; + boost::posix_time::ptime dp_time_end; + long dp_time; + // "Dynamic Programming" version of queue simulator -- copy the queue simulator containers at this point, after removal of unbuildable items, + // perform dynamic programming calculation of completion times, then after regular simulation is done compare results + + //init production queue to 'never' status + for (ProductionQueue::QueueType::iterator queue_it = m_queue.begin(); queue_it != m_queue.end(); ++queue_it) { + queue_it->turns_left_to_next_item = -1; // -1 is sentinel value indicating never to be complete. ProductionWnd checks for turns to completeion less than 0 and displays "NEVER" when appropriate + queue_it->turns_left_to_completion = -1; + } + + // duplicate simulation production queue state (post-bad-item-removal) for dynamic programming + QueueType dpsim_queue = sim_queue; + std::vector<double> dpsim_production_status = sim_production_status; + //std::vector<std::set<int> > sim_queue_element_groups = queue_element_groups; //not necessary to duplicate this since won't be further modified + std::vector<int> dpsimulation_results_to_next(production_status.size(), -1); + std::vector<int> dpsimulation_results_to_completion(production_status.size(), -1); + //std::vector<int> sim_queue_original_indices(sim_production_status.size()); //not necessary to duplicate this since won't be further modified + + const int DP_TURNS = TOO_MANY_TURNS; // track up to this many turns + const double DP_TOO_LONG_TIME = TOO_LONG_TIME; // max time in ms to spend simulating queue + + // The DP version will do calculations for one resource group at a time + // unfortunately need to copy code from SetProdQueueElementSpending in order to work it in more efficiently here + dp_time_start = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); + + //invert lookup direction of sim_queue_element_groups: + std::map< std::set<int>, std::vector<int> > elementsByGroup; + for (unsigned int i = 0; i < dpsim_queue.size(); ++i) { + elementsByGroup[ sim_queue_element_groups[i] ].push_back( i ); + } + + for (std::map<std::set<int>, double>::const_iterator groups_it = available_pp.begin(); groups_it != available_pp.end(); ++groups_it) { + int firstTurnPPAvailable = 1; //the first turn any pp in this resource group is available to the next item for this group + int turnJump = 0; + //ppStillAvailable[turn-1] gives the PP still available in this resource pool at turn "turn" + std::vector<double> ppStillAvailable(DP_TURNS, groups_it->second ); // initialize to the groups full PP allocation for each turn modeled + + std::vector<int> &thisGroupsElements = elementsByGroup[ groups_it->first ]; + std::vector<int>::const_iterator groupBegin = thisGroupsElements.begin(); + std::vector<int>::const_iterator groupEnd = thisGroupsElements.end(); + + // cycle through items on queue, if in this resource group then allocate production costs over time against those available to group + for (std::vector<int>::const_iterator el_it = groupBegin; + ( el_it != groupEnd ) && ((boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time())-dp_time_start).seconds() < DP_TOO_LONG_TIME) ; ++el_it) { + firstTurnPPAvailable += turnJump; + turnJump = 0; + if (firstTurnPPAvailable > DP_TURNS ) + break; // this resource group is allocated-out for span of simulation; remaining items in group left as never completing + + unsigned int i = *el_it; + ProductionQueue::Element& element = dpsim_queue[i]; + double item_cost; + int build_turns; + boost::tie(item_cost, build_turns) = empire->ProductionCostAndTime(element); + double element_accumulated_PP = sim_production_status[i]; // PP accumulated by this element towards building next item + double element_total_cost = item_cost * element.remaining; // total PP to build all items in this element + double element_per_turn_limit = item_cost / std::max(build_turns, 1); + double additional_pp_to_complete_element = element_total_cost - element_accumulated_PP; // additional PP, beyond already-accumulated PP, to build all items in this element + + int max_turns = std::max( std::max(build_turns, 1), 1+int(additional_pp_to_complete_element/ppStillAvailable[firstTurnPPAvailable-1])); + max_turns = std::min( max_turns, DP_TURNS - firstTurnPPAvailable +1 ); + + double allocation; + //Logger().debugStream() << "ProductionQueue::Update Queue index Queue Item: " << element.item.name; + + for (int j = 0; j < max_turns; j++ ) { //iterate over the turns necessary to complete item + // determine how many pp to allocate to this queue element this turn. allocation is limited by the + // item cost, which is the max number of PP per turn that can be put towards this item, and by the + // total cost remaining to complete the last item in the queue element (eg. the element has all but + // the last item complete already) and by the total pp available in this element's production location's + // resource sharing group + allocation = std::min( std::min( additional_pp_to_complete_element, element_per_turn_limit), ppStillAvailable[firstTurnPPAvailable+j-1] ); + allocation = std::max( allocation, 0.0); // added max (..., 0.0) to prevent any negative-allocation bugs that might come up... + dpsim_production_status[i] +=allocation; // add turn's allocation + ppStillAvailable[firstTurnPPAvailable+j-1] -= allocation; + if (ppStillAvailable[firstTurnPPAvailable+j-1] <= EPSILON ) { + ppStillAvailable[firstTurnPPAvailable+j-1] = 0; + ++turnJump; + } + + // check if additional turn's PP allocation was enough to finish next item in element + if (item_cost - EPSILON <= dpsim_production_status[i] ) { + // an item has been completed. + // deduct cost of one item from accumulated PP. don't set + // accumulation to zero, as this would eliminate any partial + // completion of the next item + dpsim_production_status[i] -= item_cost; + --element.remaining; //pretty sure this just effects the dp version & should do even if also doing ORIG_SIMULATOR + +// see ~90 lines up for define or undef statement +#ifndef ORIG_SIMULATOR + //Logger().debugStream() << "ProductionQueue::Recording DP sim results for item " << element.item.name; + + // if this was the first item in the element to be completed in + // this simuation, update the original queue element with the + // turns required to complete the next item in the element + if (element.remaining +1 == m_queue[sim_queue_original_indices[i]].remaining)//had already decremented element.remaining above + m_queue[sim_queue_original_indices[i]].turns_left_to_next_item = firstTurnPPAvailable+j; + if (!element.remaining) { + m_queue[sim_queue_original_indices[i]].turns_left_to_completion = firstTurnPPAvailable+j; // record the (estimated) turns to complete the whole element on the original queue + } +#endif // ORIG_SIMULATOR +#ifdef ORIG_SIMULATOR + //extra record of dp results, in case want to compare to orig results + if (element.remaining +1 == m_queue[sim_queue_original_indices[i]].remaining)//had already decremented element.remaining above + dpsimulation_results_to_next[i] = firstTurnPPAvailable+j; + if (!element.remaining) { + dpsimulation_results_to_completion[i] = firstTurnPPAvailable+j; // record the (estimated) turns to complete the whole element on the original queue + } +#endif // ORIG_SIMULATOR + } + if (!element.remaining) { + break; // this element all done + } + } //j-loop : turns relative to firstTurnPPAvailable + }// queue element loop + }// resource groups loop + + dp_time_end = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); + dp_time = (dp_time_end - dp_time_start).total_nanoseconds(); + dp_time = dp_time; // just to suppresss the compiler warning of unused var if the comparisons are not being done below. + + //dp_time = dpsim_queue_timer.elapsed() * 1000; + // Logger().debugStream() << "ProductionQueue::Update queue dynamic programming sim time: " << dpsim_queue_timer.elapsed() * 1000.0; + +#endif //DP_SIMULATOR + +// see ~110 lines up for define or undef statement +#ifdef ORIG_SIMULATOR + boost::posix_time::ptime orig_time_start; + boost::posix_time::ptime orig_time_end; + long orig_time; + // cycle through items on queue, adding up their allotted PP until each is // finished and removed from queue until everything on queue has been // finished, in order to calculate expected completion times - boost::timer sim_queue_timer; - while (!sim_queue.empty() && turns < TOO_MANY_TURNS && sim_queue_timer.elapsed() < TOO_LONG_TIME) { + //boost::timer sim_queue_timer; + int turns = 1; // to keep track of how man turn-iterations simulation takes to finish items + orig_time_start = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); + + while (!sim_queue.empty() && turns < TOO_MANY_TURNS && (boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time())-orig_time_start).seconds() < TOO_LONG_TIME) { std::map<std::set<int>, double> allocated_pp; int projects_in_progress = 0; @@ -777,8 +1095,11 @@ } ++turns; } // loop while (!sim_queue.empty() && turns < TOO_MANY_TURNS) - //Logger().debugStream() << "ProductionQueue::Update queue sim time: " << sim_queue_timer.elapsed() * 1000.0; - + // Logger().debugStream() << "ProductionQueue::Update queue orig sim time: " << sim_queue_timer.elapsed() * 1000.0; + //orig_time = sim_queue_timer.elapsed() *1000; + orig_time_end = boost::posix_time::ptime(boost::posix_time::microsec_clock::local_time()); + orig_time = (orig_time_end - orig_time_start).total_nanoseconds(); + orig_time = orig_time; // just to suppresss the compiler warning of unused var if the comparisons are not being done below. // mark rest of items on simulated queue (if any) as never to be finished for (unsigned int i = 0; i < sim_queue.size(); ++i) { if (sim_queue[i].remaining == m_queue[sim_queue_original_indices[i]].remaining) @@ -786,6 +1107,32 @@ m_queue[sim_queue_original_indices[i]].turns_left_to_completion = -1; } +#ifdef DP_QUEUE_SIMULATOR // if both simulations were done, compare results +#ifdef COMPARE_SIMS + bool sameResults = true; + for (unsigned int i = 0; i< sim_production_status.size(); ++i ) { + if ( (m_queue[sim_queue_original_indices[i]].turns_left_to_next_item != dpsimulation_results_to_next[i]) || + (m_queue[sim_queue_original_indices[i]].turns_left_to_completion != dpsimulation_results_to_completion[i]) ) { + sameResults = false; + break; + } + } + if (sameResults ) { + Logger().debugStream() << "ProductionQueue::Update orig sim and dp_sim gave same results"; + Logger().debugStream() << "ProductionQueue::Update orig sim time: " << orig_time*1e-3 << " , dp sim time: " << dp_time*1.0e-3 << " micro sec"; + } else { + Logger().debugStream() << "ProductionQueue::Update orig sim and dp_sim gave different results"; + Logger().debugStream() << "ProductionQueue::Update orig sim time: " << orig_time*1e-3 << " , dp sim time: " << dp_time*1.0e-3 << " micro sec"; + for (unsigned int i = 0; i< dpsimulation_results_to_next.size(); ++i ) { + ProductionQueue::Element& el = m_queue[sim_queue_original_indices[i]]; + Logger().debugStream() << "ProductionQueue::Update Queue Item: " << el.item.name; + Logger().debugStream() << "ProductionQueue::Update orig sim gave next: " << el.turns_left_to_next_item << " ; completion: " << el.turns_left_to_completion; + Logger().debugStream() << "ProductionQueue::Update dp sim gave next: " << dpsimulation_results_to_next[i] << " ; completion: " << dpsimulation_results_to_completion[i]; + } + } +#endif // COMPARE_SIMS +#endif // DP_QUEUE_SIMULATOR +#endif // ORIG_SIMULATOR ProductionQueueChangedSignal(); } @@ -1801,11 +2148,13 @@ // don't just give tech to empire, as another effect might reduce its progress before end of turn } +const int MAX_PROD_QUEUE_SIZE = 500; + void Empire::PlaceBuildInQueue(BuildType build_type, const std::string& name, int number, int location, int pos/* = -1*/) { if (!BuildableItem(build_type, name, location)) Logger().debugStream() << "Empire::PlaceBuildInQueue() : Placed a non-buildable item in queue..."; - if (m_production_queue.size() >= 100) + if (m_production_queue.size() >= MAX_PROD_QUEUE_SIZE) return; ProductionQueue::Element build(build_type, name, number, number, location); @@ -1823,7 +2172,7 @@ if (!BuildableItem(build_type, design_id, location)) Logger().debugStream() << "Empire::PlaceBuildInQueue() : Placed a non-buildable item in queue..."; - if (m_production_queue.size() >= 100) + if (m_production_queue.size() >= MAX_PROD_QUEUE_SIZE) return; ProductionQueue::Element build(build_type, design_id, number, number, location); |
From: <geo...@us...> - 2012-10-20 02:36:51
|
Revision: 5310 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5310&view=rev Author: geoffthemedio Date: 2012-10-20 02:36:43 +0000 (Sat, 20 Oct 2012) Log Message: ----------- Tech queue fix by Dilvish. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-10-19 18:50:00 UTC (rev 5309) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-10-20 02:36:43 UTC (rev 5310) @@ -365,7 +365,8 @@ std::set<std::string> thesePrereqs = tech->Prerequisites(); for (std::set<std::string>::iterator ptech_it = thesePrereqs.begin(); ptech_it != thesePrereqs.end(); ++ptech_it){ if (dpsim_tech_status_map[ *ptech_it ] == TS_COMPLETE ) { - thesePrereqs.erase( ptech_it ); + std::set<std::string>::iterator eraseit = ptech_it--; + thesePrereqs.erase( eraseit); } } waitingForPrereqs[ techname ] = thesePrereqs; |
From: <geo...@us...> - 2012-10-24 19:12:59
|
Revision: 5332 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5332&view=rev Author: geoffthemedio Date: 2012-10-24 19:12:52 +0000 (Wed, 24 Oct 2012) Log Message: ----------- Fixed calculation of production project in progress, based on suggestion by Dilvish. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-10-24 09:37:05 UTC (rev 5331) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-10-24 19:12:52 UTC (rev 5332) @@ -200,9 +200,7 @@ //Logger().debugStream() << "... leaving " << group_pp_available << " PP available to group"; - - // check if this will complete the element - if (allocation >= additional_pp_to_complete_element - EPSILON) + if (allocation > 0.9) ++projects_in_progress; } } |
From: <geo...@us...> - 2012-10-25 11:42:15
|
Revision: 5335 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5335&view=rev Author: geoffthemedio Date: 2012-10-25 11:42:04 +0000 (Thu, 25 Oct 2012) Log Message: ----------- Fixed typo pointed out by qsswin. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-10-25 07:07:30 UTC (rev 5334) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-10-25 11:42:04 UTC (rev 5335) @@ -200,7 +200,7 @@ //Logger().debugStream() << "... leaving " << group_pp_available << " PP available to group"; - if (allocation > 0.9) + if (allocation > 0.0) ++projects_in_progress; } } |
From: <geo...@us...> - 2012-10-27 02:12:46
|
Revision: 5342 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5342&view=rev Author: geoffthemedio Date: 2012-10-27 02:12:40 +0000 (Sat, 27 Oct 2012) Log Message: ----------- Fixed crash when ground combat resulted in non-empire troops capturing a planet with items on the production queue, which lead to an infinite loop on the server when trying to decide what to do with the production item. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-10-27 02:01:10 UTC (rev 5341) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-10-27 02:12:40 UTC (rev 5342) @@ -2335,8 +2335,11 @@ queue_it = queue.erase(queue_it); status.erase(status.begin() + i); + } else { + // else do nothing; no empire can't capure things + ++queue_it; + ++i; } - // else do nothing; no empire can't capure things } else if (result == INVALID_CAPTURE_RESULT) { Logger().errorStream() << "Empire::ConquerBuildsAtLocationFromEmpire: BuildingType had an invalid CaptureResult"; |
From: <geo...@us...> - 2012-11-03 16:39:17
|
Revision: 5374 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5374&view=rev Author: geoffthemedio Date: 2012-11-03 16:39:09 +0000 (Sat, 03 Nov 2012) Log Message: ----------- -Added checks in production to prevent double-production of buildings if the first one made the location not pass the location condition for the second. -grooming Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2012-11-03 12:47:40 UTC (rev 5373) +++ trunk/FreeOrion/Empire/Empire.cpp 2012-11-03 16:39:09 UTC (rev 5374) @@ -2634,9 +2634,16 @@ Planet* planet = GetPlanet(planet_id); if (!planet) { Logger().errorStream() << "Couldn't get planet with id " << planet_id << " on which to create building"; - continue; + break; } + // check location condition before each building is created, so + // that buildings being produced can prevent subsequent + // buildings completions on the same turn from going through + if (!this->BuildableItem(m_production_queue[i].item, m_production_queue[i].location)) + break; + + // create new building Building* building = new Building(m_id, m_production_queue[i].item.name, m_id); int building_id = universe.Insert(building); planet->AddBuilding(building_id); @@ -2647,16 +2654,25 @@ } case BT_SHIP: { + if (m_production_queue[i].blocksize < 1) + break; // nothing to do! + UniverseObject* build_location = GetUniverseObject(m_production_queue[i].location); System* system = universe_object_cast<System*>(build_location); if (!system && build_location) system = GetSystem(build_location->SystemID()); - // TODO: account for shipyards and/or other ship production sites that are in interstellar space, if needed + // TODO: account for shipyards and/or other ship production + // sites that are in interstellar space, if needed if (!system) { Logger().errorStream() << "Empire::CheckProductionProgress couldn't get system for building new ship"; - continue; + break; } + // check location condition before each ship is created, so + // that ships being produced can prevent subsequent + // ship completions on the same turn from going through + if (!this->BuildableItem(m_production_queue[i].item, m_production_queue[i].location)) + break; // get species for this ship. use popcenter species if build // location is a popcenter, or use ship species if build @@ -2671,10 +2687,23 @@ else if (const Planet* capital_planet = GetPlanet(this->CapitalID())) species_name = capital_planet->SpeciesName(); // else give up... - Ship* ship; - int ship_id; - ship_id = 0; - for (int count=0; count < m_production_queue[i].blocksize; count++) { + if (species_name.empty()) { + // only really a problem for colony ships, which need to have a species to function + const ShipDesign* design = GetShipDesign(m_production_queue[i].item.design_id); + if (!design) { + Logger().errorStream() << "Couldn't get ShipDesign with id: " << m_production_queue[i].item.design_id; + break; + } + if (design->CanColonize()) { + Logger().errorStream() << "Couldn't get species in order to make colony ship!"; + break; + } + } + + Ship* ship = 0; + int ship_id = INVALID_OBJECT_ID; + + for (int count = 0; count < m_production_queue[i].blocksize; count++) { // create ship ship = new Ship(m_id, m_production_queue[i].item.design_id, species_name, m_id); // set active meters that have associated max meters to an @@ -2686,27 +2715,18 @@ ship->UniverseObject::GetMeter(METER_SHIELD)->SetCurrent(Meter::LARGE_VALUE); ship->UniverseObject::GetMeter(METER_STRUCTURE)->SetCurrent(Meter::LARGE_VALUE); ship->BackPropegateMeters(); - // for colony ships, set species - if (ship->CanColonize()) - if (const PopCenter* build_loc_pop_center = dynamic_cast<const PopCenter*>(build_location)) - ship->SetSpecies(build_loc_pop_center->SpeciesName()); ship_id = universe.Insert(ship); - ship->Rename(NewShipName()); - // store ships to put into fleets later system_new_ships[system->ID()].push_back(ship); - - } // add sitrep - if (m_production_queue[i].blocksize ==1) { + if (m_production_queue[i].blocksize == 1) { AddSitRepEntry(CreateShipBuiltSitRep(ship_id, system->ID(), ship->DesignID())); Logger().debugStream() << "New Ship, id " << ship_id << ", created on turn: " << ship->CreationTurn(); - } - else { + } else { AddSitRepEntry(CreateShipBlockBuiltSitRep(system->ID(), ship->DesignID(), m_production_queue[i].blocksize)); Logger().debugStream() << "New block of "<< m_production_queue[i].blocksize << "ships created on turn: " << ship->CreationTurn(); } @@ -2718,7 +2738,6 @@ break; } - if (!--m_production_queue[i].remaining) // decrement number of remaining items to be produced in current queue element to_erase.push_back(i); // remember completed element so that it can be removed from queue } @@ -2737,38 +2756,38 @@ std::vector<Ship*>& allShips = it->second; if (allShips.empty()) continue; - + //group ships into fleets, by design - std::map<int,std::vector<Ship*> > shipsByDesign; for (std::vector<Ship*>::iterator it = allShips.begin(); it != allShips.end(); ++it) { Ship* ship = *it; shipsByDesign[ship->DesignID()].push_back(ship); } for (std::map<int, std::vector<Ship*> >::iterator design_it = shipsByDesign.begin(); - design_it != shipsByDesign.end(); ++design_it) { - std::vector<int> ship_ids; - - std::vector<Ship*>& ships = design_it->second; - if (ships.empty()) - continue; - - // create new fleet for ships - Fleet* fleet = new Fleet("", system->X(), system->Y(), m_id); - int fleet_id = universe.Insert(fleet); + design_it != shipsByDesign.end(); ++design_it) + { + std::vector<int> ship_ids; - system->Insert(fleet); + std::vector<Ship*>& ships = design_it->second; + if (ships.empty()) + continue; - for (std::vector<Ship*>::iterator it = ships.begin(); it != ships.end(); ++it) { - Ship* ship = *it; - ship_ids.push_back(ship->ID()); - fleet->AddShip(ship->ID()); - } + // create new fleet for ships + Fleet* fleet = new Fleet("", system->X(), system->Y(), m_id); + int fleet_id = universe.Insert(fleet); - // rename fleet, given its id and the ship that is in it - fleet->Rename(Fleet::GenerateFleetName(ship_ids, fleet_id)); + system->Insert(fleet); - Logger().debugStream() << "New Fleet \"" + fleet->Name() + "\"created on turn: " << fleet->CreationTurn(); + for (std::vector<Ship*>::iterator it = ships.begin(); it != ships.end(); ++it) { + Ship* ship = *it; + ship_ids.push_back(ship->ID()); + fleet->AddShip(ship->ID()); + } + + // rename fleet, given its id and the ship that is in it + fleet->Rename(Fleet::GenerateFleetName(ship_ids, fleet_id)); + + Logger().debugStream() << "New Fleet \"" + fleet->Name() + "\"created on turn: " << fleet->CreationTurn(); } } |
From: <dil...@us...> - 2013-01-20 15:54:02
|
Revision: 5660 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5660&view=rev Author: dilvish-fo Date: 2013-01-20 15:53:55 +0000 (Sun, 20 Jan 2013) Log Message: ----------- fixes transfer of in-progress production-queue building type element upon planet capture, so that current progress is also transferred, not just a totally incomplete new element Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-01-20 13:09:41 UTC (rev 5659) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-01-20 15:53:55 UTC (rev 5660) @@ -2080,6 +2080,7 @@ if (to_empire) { // item removed from current queue, added to conquerer's queue ProductionQueue::Element build(item, elem.ordered, elem.remaining, location_id); + build.progress=elem.progress; to_empire->m_production_queue.push_back(build); queue_it = queue.erase(queue_it); |
From: <dil...@us...> - 2013-02-10 19:51:29
|
Revision: 5748 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5748&view=rev Author: dilvish-fo Date: 2013-02-10 19:51:18 +0000 (Sun, 10 Feb 2013) Log Message: ----------- fixed UnderFundedProject Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-02-10 14:39:02 UTC (rev 5747) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-02-10 19:51:18 UTC (rev 5748) @@ -252,12 +252,11 @@ for (const_iterator it = begin(); it != end(); ++it) { if (const Tech* tech = GetTech(it->name)) { if (it->allocated_rp && - it->allocated_rp < tech->ResearchCost(m_empire_id) + it->allocated_rp < tech->PerTurnCost(m_empire_id) && 1 < it->turns_left) { return it; } - return end(); } } return end(); |
From: <geo...@us...> - 2013-02-22 13:35:18
|
Revision: 5778 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5778&view=rev Author: geoffthemedio Date: 2013-02-22 13:35:06 +0000 (Fri, 22 Feb 2013) Log Message: ----------- Commented out some logging. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-02-22 13:34:38 UTC (rev 5777) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-02-22 13:35:06 UTC (rev 5778) @@ -127,7 +127,7 @@ // get resource sharing group and amount of resource available to build this item const std::set<int>& group = queue_element_resource_sharing_object_groups[i]; if (group.empty()) { - Logger().debugStream() << "resource sharing group for queue element is empty. not allocating any resources to element"; + //Logger().debugStream() << "resource sharing group for queue element is empty. not allocating any resources to element"; queue_element.allocated_pp = 0.0; continue; } @@ -135,7 +135,7 @@ std::map<std::set<int>, double>::iterator available_pp_it = available_pp.find(group); if (available_pp_it == available_pp.end()) { // item is not being built at an object that has access to resources, so it can't be built. - Logger().debugStream() << "no resource sharing group for production queue element"; + //Logger().debugStream() << "no resource sharing group for production queue element"; queue_element.allocated_pp = 0.0; continue; } @@ -155,7 +155,7 @@ if (!empire->BuildableItem(queue_element.item, queue_element.location)) { // can't be built at this location this turn. queue_element.allocated_pp = 0.0; - Logger().debugStream() << "item can't be built at location this turn"; + //Logger().debugStream() << "item can't be built at location this turn"; continue; } |
From: <geo...@us...> - 2013-02-25 05:53:24
|
Revision: 5805 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5805&view=rev Author: geoffthemedio Date: 2013-02-25 05:53:17 +0000 (Mon, 25 Feb 2013) Log Message: ----------- fixed warning Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-02-25 01:15:48 UTC (rev 5804) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-02-25 05:53:17 UTC (rev 5805) @@ -1801,8 +1801,8 @@ const Universe& universe = GetUniverse(); const ObjectMap& objects = universe.Objects(); - for (ObjectMap::const_value_iterator<System> sys_it = Objects().begin_values<System>(); - sys_it != Objects().end_values<System>(); ++sys_it) + for (ObjectMap::const_value_iterator<System> sys_it = objects.begin_values<System>(); + sys_it != objects.end_values<System>(); ++sys_it) { int start_id = sys_it->ID(); |
From: <geo...@us...> - 2013-03-10 08:19:24
|
Revision: 5851 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5851&view=rev Author: geoffthemedio Date: 2013-03-10 08:19:18 +0000 (Sun, 10 Mar 2013) Log Message: ----------- Safety check / grooming. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-03-10 03:22:04 UTC (rev 5850) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-03-10 08:19:18 UTC (rev 5851) @@ -487,14 +487,14 @@ ProductionQueue::ProductionItem::ProductionItem(BuildType build_type_, int design_id_) : build_type(build_type_), - name(std::string("")), + name(), design_id(design_id_) { if (build_type == BT_SHIP) { - const ShipDesign* ship_design = GetShipDesign(design_id); - name = ship_design->Name(); - } else { - name = "???"; + if (const ShipDesign* ship_design = GetShipDesign(design_id)) + name = ship_design->Name(); + else + Logger().errorStream() << "ProductionItem::ProductionItem couldn't get ship design with id: " << design_id; } } |
From: <dil...@us...> - 2013-04-20 15:58:01
|
Revision: 5988 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=5988&view=rev Author: dilvish-fo Date: 2013-04-20 15:57:52 +0000 (Sat, 20 Apr 2013) Log Message: ----------- Increased amount of time the production queue forward projections can take Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-04-19 18:13:29 UTC (rev 5987) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-04-20 15:57:52 UTC (rev 5988) @@ -770,7 +770,7 @@ const int TOO_MANY_TURNS = 500; // stop counting turns to completion after this long, to prevent seemingly endless loops - const double TOO_LONG_TIME = 0.1; // max time in ms to spend simulating queue + const double TOO_LONG_TIME = 0.5; // max time in ms to spend simulating queue // remove from simulated queue any items that can't be built due to not |
From: <geo...@us...> - 2013-05-05 21:29:50
|
Revision: 6002 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=6002&view=rev Author: geoffthemedio Date: 2013-05-05 21:29:43 +0000 (Sun, 05 May 2013) Log Message: ----------- Commented out requirement that a ship design be kept by an empire to be producible. Modified Paths: -------------- trunk/FreeOrion/Empire/Empire.cpp Modified: trunk/FreeOrion/Empire/Empire.cpp =================================================================== --- trunk/FreeOrion/Empire/Empire.cpp 2013-05-05 21:14:36 UTC (rev 6001) +++ trunk/FreeOrion/Empire/Empire.cpp 2013-05-05 21:29:43 UTC (rev 6002) @@ -1244,9 +1244,9 @@ } bool Empire::ShipDesignAvailable(int ship_design_id) const { - // if design isn't kept by this empire, it can't be built. - if (!ShipDesignKept(ship_design_id)) - return false; // The empire needs to issue a ShipDesignOrder to add this design id to its kept designs + //// if design isn't kept by this empire, it can't be built. + //if (!ShipDesignKept(ship_design_id)) + // return false; // The empire needs to issue a ShipDesignOrder to add this design id to its kept designs const ShipDesign* design = GetShipDesign(ship_design_id); if (!design || !design->Producible()) return false; |