Revision: 6140
http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=6140&view=rev
Author: dilvish-fo
Date: 2013-06-11 07:59:03 +0000 (Tue, 11 Jun 2013)
Log Message:
-----------
harmonizes supply blocks and blockades; enforces blockades
Modified Paths:
--------------
trunk/FreeOrion/Empire/Empire.cpp
trunk/FreeOrion/Empire/Empire.h
trunk/FreeOrion/UI/MapWnd.cpp
trunk/FreeOrion/UI/TechTreeWnd.cpp
trunk/FreeOrion/python/PythonEmpireWrapper.cpp
trunk/FreeOrion/server/ServerApp.cpp
trunk/FreeOrion/server/ServerApp.h
trunk/FreeOrion/universe/Fleet.cpp
trunk/FreeOrion/universe/Fleet.h
trunk/FreeOrion/util/SerializeEmpire.cpp
Modified: trunk/FreeOrion/Empire/Empire.cpp
===================================================================
--- trunk/FreeOrion/Empire/Empire.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/Empire/Empire.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -1474,6 +1474,22 @@
UpdateSystemSupplyRanges(known_objects_set);
}
+void Empire::UpdateUnobstructedFleets() {
+ const std::set<int>& known_destroyed_objects = GetUniverse().EmpireKnownDestroyedObjectIDs(this->EmpireID());
+ for (std::set<int>::const_iterator sys_it = m_supply_unobstructed_systems.begin(); sys_it != m_supply_unobstructed_systems.end(); ++sys_it) {
+ const System* system = GetSystem(*sys_it);
+ std::vector<int> fleet_ids = system->FindObjectIDs<Fleet>();
+ for (std::vector<int>::iterator fleet_it = fleet_ids.begin(); fleet_it != fleet_ids.end(); fleet_it++) {
+ if (known_destroyed_objects.find(*fleet_it) == known_destroyed_objects.end()) {
+ if (Fleet* fleet = GetFleet(*fleet_it) ) {
+ if (fleet->OwnedBy(m_id))
+ fleet->SetArrivalStarlane(*sys_it);
+ }
+ }
+ }
+ }
+}
+
void Empire::UpdateSupplyUnobstructedSystems() {
Universe& universe = GetUniverse();
@@ -1506,9 +1522,21 @@
const std::vector<Fleet*> fleets = GetUniverse().Objects().FindObjects<Fleet>();
const std::set<int>& known_destroyed_objects = GetUniverse().EmpireKnownDestroyedObjectIDs(this->EmpireID());
- // find systems that contain friendly fleets or objects that can block supply
+ // find systems that contain fleets that can either maintaining supply or block supply
+ // to affect supply in either manner a fleet must be armed & aggressive, & must be not
+ // trying to depart the systme. Qualifying enemy fleets will blockade if no friendly fleets
+ // are present, or if the friendly fleets were already blockade-restricted and the enemy
+ // fleets were not (meaning that the enemy fleets were continuing an existing blockade)
+ // Friendly fleets can preserve available starlane accesss even if they are trying to leave the system
+
+ // Unrestricted lane access (i.e, (fleet->ArrivalStarlane() == system->ID()) ) is used as a proxy for
+ // order of arrival -- if an enemy has unrestricted lane access and you don't, they must have arrived
+ // before you, or be in cahoots with someone who did.
std::set<int> systems_containing_friendly_fleets;
+ std::set<int> systems_with_lane_preserving_fleets;
+ std::set<int> unrestricted_friendly_systems;
std::set<int> systems_containing_obstructing_objects;
+ std::set<int> unrestricted_obstruction_systems;
for (std::vector<Fleet*>::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
const Fleet* fleet = *it;
int system_id = fleet->SystemID();
@@ -1516,16 +1544,28 @@
continue; // not in a system, so can't affect system obstruction
} else if (known_destroyed_objects.find(fleet->ID()) != known_destroyed_objects.end()) {
continue; //known to be destroyed so can't affect supply, important just in case being updated on client side
- } else if (fleet->OwnedBy(m_id) && fleet->HasArmedShips() && fleet->Aggressive()) {
- systems_containing_friendly_fleets.insert(system_id);
- } else if (fleet->HasArmedShips() && fleet->Aggressive()) {
- int fleet_owner = fleet->Owner();
- if (fleet_owner == ALL_EMPIRES || Empires().GetDiplomaticStatus(m_id, fleet_owner) == DIPLO_WAR)
- systems_containing_obstructing_objects.insert(system_id);
}
+ if (fleet->HasArmedShips() && fleet->Aggressive()) {
+ if (fleet->OwnedBy(m_id)) {
+ if (fleet->NextSystemID()==INVALID_OBJECT_ID) {
+ systems_containing_friendly_fleets.insert(system_id);
+ if (fleet->ArrivalStarlane()==system_id)
+ unrestricted_friendly_systems.insert(system_id);
+ } else {
+ systems_with_lane_preserving_fleets.insert(system_id);
+ }
+ } else if (fleet->NextSystemID()==INVALID_OBJECT_ID) {
+ int fleet_owner = fleet->Owner();
+ if (fleet_owner == ALL_EMPIRES || Empires().GetDiplomaticStatus(m_id, fleet_owner) == DIPLO_WAR) {
+ systems_containing_obstructing_objects.insert(system_id);
+ if (fleet->ArrivalStarlane()==system_id)
+ unrestricted_obstruction_systems.insert(system_id);
+ }
+ }
+ }
}
- // check each potential supplyable system for whether it can propegate supply.
+ // check each potential supplyable system for whether it can propagate supply.
for (std::set<int>::const_iterator known_systems_it = known_systems.begin(); known_systems_it != known_systems.end(); ++known_systems_it) {
int sys_id = *known_systems_it;
@@ -1533,22 +1573,60 @@
if (systems_with_at_least_partial_visibility_at_some_point.find(sys_id) == systems_with_at_least_partial_visibility_at_some_point.end())
continue;
- // if system is explored, then whether it can propegate supply depends
+ // if system is explored, then whether it can propagate supply depends
// on what friendly / enemy ships are in the system
- if (systems_containing_friendly_fleets.find(sys_id) != systems_containing_friendly_fleets.end()) {
- // if there are friendly ships, supply can propegate
+ if (unrestricted_friendly_systems.find(sys_id) != unrestricted_friendly_systems.end())
+ {
+ // if there are unrestricted friendly ships, supply can propagate
m_supply_unobstructed_systems.insert(sys_id);
+ } else if (systems_containing_friendly_fleets.find(sys_id) != systems_containing_friendly_fleets.end()) {
+ if (unrestricted_obstruction_systems.find(sys_id) == unrestricted_obstruction_systems.end()) {
+ // if there are (previously) restricted friendly ships, and no unrestricted enemy fleets, supply can propagate
+ m_supply_unobstructed_systems.insert(sys_id);
+ }
} else if (systems_containing_obstructing_objects.find(sys_id) == systems_containing_obstructing_objects.end()) {
// if there are no friendly ships and no enemy ships, supply can propegate
m_supply_unobstructed_systems.insert(sys_id);
+ } else if (systems_with_lane_preserving_fleets.find(sys_id) == systems_with_lane_preserving_fleets.end()) {
+ // otherwise, if system contains no friendly fleets capable of maintaining lane access but does contain an
+ // unfriendly fleet, so it is obstructed, so isn't included in the
+ // unobstructed systems set. Furthermore, this empire's available
+ // system exit lanes for this system are cleared
+ if (!m_available_system_exit_lanes[sys_id].empty()) {
+ //Logger().debugStream() << "Empire::UpdateSupplyUnobstructedSystems clearing available lanes for system ("<<sys_id<<"); available lanes were:";
+ //for (std::set<int>::iterator lane_it = m_available_system_exit_lanes[sys_id].begin(); lane_it != m_available_system_exit_lanes[sys_id].end(); lane_it++)
+ // Logger().debugStream() << "...... "<< *lane_it;
+ m_available_system_exit_lanes[sys_id].clear();
+ }
}
- // otherwise, system contains no friendly fleets but does contain an
- // unfriendly fleet, so it is obstructed, so isn't included in the
- // unobstructed systems set
}
}
+void Empire::RecordPendingLaneUpdate(int start_system_id, int dest_system_id) {
+ if (m_supply_unobstructed_systems.find(start_system_id) == m_supply_unobstructed_systems.end()) {
+ //Logger().debugStream() << "Empire::UpdateAvailableLane for system ("<< start_system_id <<") adding lane to ("<<dest_system_id <<")";
+ m_pending_system_exit_lanes[start_system_id].insert(dest_system_id);
+ } else { // if the system is unobstructed, mark all its lanes as avilable
+ //Logger().debugStream() << "Empire::UpdateAvailableLane for system ("<< start_system_id <<") adding all lanes";
+ const System* system = GetSystem(start_system_id);
+ for (System::const_lane_iterator lane_it = system->begin_lanes(); lane_it != system->end_lanes(); lane_it++) {
+ m_pending_system_exit_lanes[start_system_id].insert(lane_it->first); // will add both starlanes and wormholes
+ //Logger().debugStream() << "..... lane "<< lane_it->first;
+ }
+ }
+}
+
+void Empire::UpdateAvailableLanes() {
+ for (std::map<int, std::set<int> >::iterator sys_it = m_pending_system_exit_lanes.begin();
+ sys_it != m_pending_system_exit_lanes.end(); sys_it++)
+ {
+ m_available_system_exit_lanes[sys_it->first].insert(sys_it->second.begin(), sys_it->second.end());
+ sys_it->second.clear();
+ }
+ m_pending_system_exit_lanes.clear(); // TODO: consider: not really necessary, & may be more efficient to not clear.
+}
+
void Empire::UpdateSupply()
{ UpdateSupply(this->KnownStarlanes()); }
@@ -1761,7 +1839,7 @@
const std::set<std::pair<int, int> >& Empire::SupplyStarlaneTraversals() const
{ return m_supply_starlane_traversals; }
-const std::set<std::pair<int, int> >& Empire::SupplyOstructedStarlaneTraversals() const
+const std::set<std::pair<int, int> >& Empire::SupplyObstructedStarlaneTraversals() const
{ return m_supply_starlane_obstructed_traversals; }
const std::set<int>& Empire::FleetSupplyableSystemIDs() const
@@ -1775,6 +1853,15 @@
return false;
}
+const bool Empire::UnrestrictedLaneTravel(int start_system_id, int dest_system_id) const {
+ std::map<int, std::set<int> >::const_iterator find_it = m_available_system_exit_lanes.find(start_system_id);
+ if (find_it != m_available_system_exit_lanes.end() ) {
+ if (find_it->second.find(dest_system_id) != find_it->second.end())
+ return true;
+ }
+ return false;
+}
+
const std::set<std::set<int> >& Empire::ResourceSupplyGroups() const
{ return m_resource_supply_groups; }
Modified: trunk/FreeOrion/Empire/Empire.h
===================================================================
--- trunk/FreeOrion/Empire/Empire.h 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/Empire/Empire.h 2013-06-11 07:59:03 UTC (rev 6140)
@@ -349,7 +349,7 @@
/** Returns set of directed starlane traversals along which supply could
* flow for this empire, but which can't due to some obstruction in one
* of the systems. */
- const std::set<std::pair<int, int> >& SupplyOstructedStarlaneTraversals() const;
+ const std::set<std::pair<int, int> >& SupplyObstructedStarlaneTraversals() const;
/** Returns set of system ids where fleets can be supplied by this empire
* (as determined by object supply meters and rules of supply propagation
* and blockade). */
@@ -357,6 +357,8 @@
/** Returns true if system with id \a system_id is fleet supplyable or in
* one of the resource supply groups of this empire. */
bool SystemHasFleetSupply(int system_id) const;
+ /** Returns true if the start system is known to this empire and travel to the dest system is not restricted by blockade */
+ const bool UnrestrictedLaneTravel(int start_system_id, int dest_system_id) const;
/** Returns set of sets of systems that can share industry (systems in
* separate groups are blockaded or otherwise separated). */
const std::set<std::set<int> >& ResourceSupplyGroups() const;
@@ -470,6 +472,13 @@
/** Calculates systems that can propegate supply using this empire's own /
* internal list of explored systems. */
void UpdateSupplyUnobstructedSystems();
+ /** Updates fleet ArrivalStarlane to flag fleets of this empire that are not blockaded post-combat
+ * must be done after *all* noneliminated empires have updated their unobstructed systems* */
+ void UpdateUnobstructedFleets();
+ /** Records, in a list of pending updates, the start_system exit lane to the specified destination as accessible to this empire*/
+ void RecordPendingLaneUpdate(int start_system_id, int dest_system_id);
+ /** Processes all the pending lane access updates. This is managed as a two step process to avoid order-of-processing issues. */
+ void UpdateAvailableLanes();
/** Calculates systems at which fleets of this empire can be supplied, and
* groups of systems that can exchange resources, and the starlane
* traversals used to do so, using the indicated \a starlanes but subject
@@ -590,6 +599,8 @@
std::set<int> m_supply_unobstructed_systems; ///< ids of system that don't block supply from flowing
std::set<std::pair<int, int> > m_supply_starlane_traversals; ///< ordered pairs of system ids between which a starlane runs that can be used to convey resources between systems
std::set<std::pair<int, int> > m_supply_starlane_obstructed_traversals;///< ordered pairs of system ids between which a starlane could be used to convey resources between system, but is not because something is obstructing the resource flow. That is, the resource flow isn't limited by range, but by something blocking its flow.
+ std::map<int, std::set<int> > m_available_system_exit_lanes; ///< for each system known to this empire, the set of available/non-blockaded exit lanes for fleet travel
+ std::map<int, std::set<int> > m_pending_system_exit_lanes; ///< pending updates to m_available_system_exit_lanes
std::set<int> m_fleet_supplyable_system_ids; ///< ids of systems where fleets can remain for a turn to be resupplied.
std::set<std::set<int> > m_resource_supply_groups; ///< sets of system ids that are connected by supply lines and are able to share resources between systems or between objects in systems
Modified: trunk/FreeOrion/UI/MapWnd.cpp
===================================================================
--- trunk/FreeOrion/UI/MapWnd.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/UI/MapWnd.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -426,6 +426,7 @@
if (empire) {
unobstructed = empire->SupplyUnobstructedSystems();
calc_s_flag = true;
+ //s_flag = ((first_node.object_id != INVALID_OBJECT_ID) && unobstructed.find(first_node.object_id)==unobstructed.end());
}
for (std::list<MovePathNode>::const_iterator path_it = path.begin(); path_it != path.end(); ++path_it) {
@@ -452,7 +453,6 @@
// if this node is later in the path, prev_sys_id should have been set in previous loop iteration
}
-
// skip invalid line segments
if (prev_sys_id == next_sys_id || next_sys_id == INVALID_OBJECT_ID || prev_sys_id == INVALID_OBJECT_ID)
continue;
@@ -477,9 +477,9 @@
// 3) Add points for line segment to list of Vertices
- bool b_flag = path_it->post_blockade;
+ bool b_flag = node.post_blockade;
s_flag = s_flag || (calc_s_flag &&
- ((path_it->object_id != INVALID_OBJECT_ID) && unobstructed.find(path_it->object_id)==unobstructed.end()));
+ ((node.object_id != INVALID_OBJECT_ID) && unobstructed.find(node.object_id)==unobstructed.end()));
vertices.push_back(Vertex(start_xy.first, start_xy.second, prev_eta, false, b_flag, s_flag));
vertices.push_back(Vertex(end_xy.first, end_xy.second, node.eta, node.turn_end, b_flag, s_flag));
@@ -2596,8 +2596,8 @@
GG::Clr eclr= this_client_empire->Color();
lane_colour = GG::DarkColor( GG::Clr(255-eclr.r, 255-eclr.g, 255-eclr.b, eclr.a));
}
- /*if ((this_client_empire->SupplyOstructedStarlaneTraversals().find(lane_forward) != this_client_empire->SupplyOstructedStarlaneTraversals().end()) ||
- (this_client_empire->SupplyOstructedStarlaneTraversals().find(lane_backward) != this_client_empire->SupplyOstructedStarlaneTraversals().end()) ||
+ /*if ((this_client_empire->SupplyObstructedStarlaneTraversals().find(lane_forward) != this_client_empire->SupplyObstructedStarlaneTraversals().end()) ||
+ (this_client_empire->SupplyObstructedStarlaneTraversals().find(lane_backward) != this_client_empire->SupplyObstructedStarlaneTraversals().end()) ||
!( (this_client_empire->SupplyStarlaneTraversals().find(lane_forward) != this_client_empire->SupplyStarlaneTraversals().end()) ||
(this_client_empire->SupplyStarlaneTraversals().find(lane_backward) != this_client_empire->SupplyStarlaneTraversals().end()) ) ) */
if (resGroupCores[ memberToPool[start_system->ID()]] != resGroupCores[ memberToPool[dest_system->ID()]])
@@ -2619,7 +2619,7 @@
for (EmpireManager::iterator empire_it = Empires().begin(); empire_it != Empires().end(); ++empire_it) {
Empire* empire = empire_it->second;
- const std::set<std::pair<int, int> >& resource_obstructed_supply_lanes = empire->SupplyOstructedStarlaneTraversals();
+ const std::set<std::pair<int, int> >& resource_obstructed_supply_lanes = empire->SupplyObstructedStarlaneTraversals();
// see if this lane exists in this empire's supply propegation lanes set. either direction accepted.
if (resource_obstructed_supply_lanes.find(lane_forward) != resource_obstructed_supply_lanes.end()) {
@@ -3025,7 +3025,8 @@
// get colour: empire colour, or white if no single empire applicable
GG::Clr line_colour = GG::CLR_WHITE;
- if (const Empire* empire = Empires().Lookup(fleet->Owner()))
+ const Empire* empire = Empires().Lookup(fleet->Owner());
+ if (empire)
line_colour = empire->Color();
else if (fleet->Unowned() && fleet->HasMonsters())
line_colour = GG::CLR_RED;
@@ -3033,16 +3034,24 @@
// create and store line
std::list<int> route(fleet->TravelRoute());
std::list<MovePathNode> path = fleet->MovePath(route, true);
- if (!route.empty() && fleet->SystemID() == route.front() && fleet->BlockadedAtSystem(route.front())) { //adjust ETAs if necessary
- //if (!route.empty() && fleet->SystemID()==route.front() && (++(path.begin()))->post_blockade) {
- std::list<int>::iterator route_it = ++route.begin();
- //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" blockaded at system "<< route.front() <<
- //" with m_arrival_lane "<< fleet->ArrivalStarlane()<<" and next destination "<<*route_it;
- if (route_it != route.end() && *route_it != fleet->ArrivalStarlane()) {
- for (std::list<MovePathNode>::iterator it = path.begin(); it != path.end(); ++it) {
- Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" node obj " << it->object_id <<
- ", node lane end " << it->lane_end_id << ", is post-blockade (" << it->post_blockade << ")";
- it->eta++;
+ std::list<int>::iterator route_it = route.begin();
+ if (!route.empty() && (++route_it) != route.end()) {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" checking for blockade at system "<< route.front() <<
+ // " with m_arrival_lane "<< fleet->ArrivalStarlane()<<" and next destination "<<*route_it;
+ if (fleet->SystemID() == route.front() && fleet->BlockadedAtSystem(route.front(), *route_it)) { //adjust ETAs if necessary
+ //if (!route.empty() && fleet->SystemID()==route.front() && (++(path.begin()))->post_blockade) {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" blockaded at system "<< route.front() <<
+ // " with m_arrival_lane "<< fleet->ArrivalStarlane()<<" and next destination "<<*route_it;
+ if (route_it != route.end() && !( (*route_it == fleet->ArrivalStarlane()) ||
+ (empire && empire->UnrestrictedLaneTravel(fleet->SystemID(), *route_it)) ) )
+ {
+ for (std::list<MovePathNode>::iterator it = path.begin(); it != path.end(); ++it) {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" node obj " << it->object_id <<
+ // ", node lane end " << it->lane_end_id << ", is post-blockade (" << it->post_blockade << ")";
+ it->eta++;
+ }
+ } else {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" slips through second block check";
}
}
}
@@ -3065,6 +3074,8 @@
RemoveProjectedFleetMovementLine(fleet_id);
return;
}
+ //std::cout << "creating projected fleet movement line for fleet at (" << fleet->X() << ", " << fleet->Y() << ")" << std::endl;
+ const Empire* empire = Empires().Lookup(fleet->Owner());
// get move path to show. if there isn't one, show nothing
std::list<MovePathNode> path = fleet->MovePath(travel_route, true);
@@ -3073,24 +3084,27 @@
RemoveProjectedFleetMovementLine(fleet_id);
return;
}
-
- if (!travel_route.empty() && fleet->SystemID()==travel_route.front() && fleet->BlockadedAtSystem(travel_route.front())) {
- //if (!route.empty() && fleet->SystemID()==route.front() && (++(path.begin()))->post_blockade) {
- std::list<int>::const_iterator route_it = ++travel_route.begin();
- //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" blockaded at system "<< route.front() <<
- //" with m_arrival_lane "<< fleet->ArrivalStarlane()<<" and next destination "<<*route_it;
- if (route_it != travel_route.end() && *route_it != fleet->ArrivalStarlane()) {
- for (std::list<MovePathNode>::iterator it = path.begin(); it != path.end(); ++it) {
- Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id << " node obj " << it->object_id <<
- ", node lane end " << it->lane_end_id << ", is post-blockade (" << it->post_blockade << ")";
- it->eta++;
+ std::list<int>::const_iterator route_it = travel_route.begin();
+ if (!travel_route.empty() && (++route_it) != travel_route.end()) {
+ if (fleet->SystemID() == travel_route.front() && fleet->BlockadedAtSystem(travel_route.front(), *route_it)) { //adjust ETAs if necessary
+ //if (!route.empty() && fleet->SystemID()==route.front() && (++(path.begin()))->post_blockade) {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id<<" blockaded at system "<< route.front() <<
+ //" with m_arrival_lane "<< fleet->ArrivalStarlane()<<" and next destination "<<*route_it;
+ if (route_it != travel_route.end() && !((*route_it == fleet->ArrivalStarlane()) ||
+ (empire && empire->UnrestrictedLaneTravel(fleet->SystemID(), *route_it))))
+ {
+ for (std::list<MovePathNode>::iterator it = path.begin(); it != path.end(); ++it) {
+ //Logger().debugStream() << "MapWnd::SetFleetMovementLine fleet id " << fleet_id << " node obj " << it->object_id <<
+ // ", node lane end " << it->lane_end_id << ", is post-blockade (" << it->post_blockade << ")";
+ it->eta++;
+ }
}
}
}
-
+
// get colour: empire colour, or white if no single empire applicable
GG::Clr line_colour = GG::CLR_WHITE;
- if (const Empire* empire = Empires().Lookup(fleet->Owner()))
+ if (empire)
line_colour = empire->Color();
// create and store line
Modified: trunk/FreeOrion/UI/TechTreeWnd.cpp
===================================================================
--- trunk/FreeOrion/UI/TechTreeWnd.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/UI/TechTreeWnd.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -144,7 +144,8 @@
it->second->MarkNotSelected();
// create buttons to switch between tree and list views
- m_list_view_button = new CUIButton(GG::X0, GG::Y0, GG::X(80), UserString("TECH_WND_LIST_VIEW"));
+ //m_list_view_button = new CUIButton(GG::X0, GG::Y0, GG::X(80), UserString("TECH_WND_LIST_VIEW"));
+ m_list_view_button = new CUIButton(GG::X0, GG::Y0, GG::X(80), "LoadMyTechs");
m_list_view_button->MarkNotSelected();
AttachChild(m_list_view_button);
m_tree_view_button = new CUIButton(GG::X0, GG::Y(30), GG::X(80), UserString("TECH_WND_TREE_VIEW"));
@@ -1702,7 +1703,8 @@
// connect view type selectors
GG::Connect(m_tech_tree_controls->m_tree_view_button->LeftClickedSignal, &TechTreeWnd::ShowTreeView, this);
- GG::Connect(m_tech_tree_controls->m_list_view_button->LeftClickedSignal, &TechTreeWnd::ShowListView, this);
+ //GG::Connect(m_tech_tree_controls->m_list_view_button->LeftClickedSignal, &TechTreeWnd::ShowListView, this);
+ GG::Connect(m_tech_tree_controls->m_list_view_button->LeftClickedSignal, &TechTreeWnd::AddMyTechs, this);
ShowAllCategories();
ShowStatus(TS_RESEARCHABLE);
@@ -1926,3 +1928,235 @@
tech_vec.push_back(tech_name);
AddTechsToQueueSignal(tech_vec, queue_pos);
}
+
+void TechTreeWnd::AddMyTechs() {
+ const int firstline=1898;
+ const int lastline= 2006;
+ const int numTechs= lastline-firstline+1;
+ const char* techs[] = {
+ "SHP_WEAPON_1_2",
+ "GRO_PLANET_ECOL",
+ "SHP_DOMESTIC_MONSTER",
+ "SHP_ORG_HULL",
+ "SHP_WEAPON_1_3",
+ "GRO_SUBTER_HAB",
+ "LRN_ALGO_ELEGANCE",
+ "SHP_WEAPON_1_4",
+ "PRO_ROBOTIC_PROD",
+ "LRN_ARTIF_MINDS",
+ "CON_ENV_ENCAPSUL",
+ "DEF_DEFENSE_NET_1",
+ "PRO_FUSION_GEN",
+ "PRO_INDUSTRY_CENTER_I",
+ "DEF_GARRISON_1",
+ "LRN_FORCE_FIELD",
+ "CON_ORBITAL_CON",
+ "PRO_ORBITAL_GEN",
+ "SHP_ZORTRIUM_PLATE",
+ "GRO_SYMBIOTIC_BIO",
+ "SHP_WEAPON_2_1",
+ "SHP_WEAPON_2_2",
+ "SHP_DEFLECTOR_SHIELD",
+ "SHP_WEAPON_2_3",
+ "DEF_DEFENSE_NET_2",
+ "DEF_DEFENSE_NET_REGEN_1",
+ "SPY_DETECT_2",
+ "SHP_WEAPON_2_4",
+ "PRO_INDUSTRY_CENTER_II",
+ "PRO_MICROGRAV_MAN",
+ "PRO_SOL_ORB_GEN",
+ "SHP_BASIC_DAM_CONT",
+ "GRO_GENETIC_ENG",
+ "DEF_GARRISON_2",
+ "GRO_XENO_GENETICS",
+ "SPY_DETECT_3",
+ "CON_METRO_INFRA",
+ "SHP_WEAPON_3_1",
+ "SHP_DIAMOND_PLATE",
+ "GRO_LIFECYCLE_MAN",
+ "SHP_MULTICELL_CAST",
+ "SHP_ENDOCRINE_SYSTEMS",
+ "DEF_PLAN_BARRIER_SHLD_1",
+ "SHP_WEAPON_3_2",
+ "CON_FRC_ENRG_STRC",
+ "SHP_ADV_DAM_CONT",
+ "LRN_QUANT_NET",
+ "SHP_WEAPON_3_3",
+ "DEF_PLAN_BARRIER_SHLD_2",
+ "LRN_GRAVITONICS",
+ "SHP_REINFORCED_HULL",
+ "CON_CONTGRAV_ARCH",
+ "LRN_PHYS_BRAIN",
+ "LRN_TRANSLING_THT",
+ "PRO_SENTIENT_AUTOMATION",
+ "PRO_EXOBOTS",
+ "LRN_XENOARCH",
+ "SHP_WEAPON_3_4",
+ "DEF_DEFENSE_NET_3",
+ "DEF_SYST_DEF_MINE_1",
+ "DEF_PLAN_BARRIER_SHLD_3",
+ "CON_ORBITAL_HAB",
+ "DEF_GARRISON_3",
+ "SHP_CONT_SYMB",
+ "SHP_MONOCELL_EXP",
+ "SHP_BIOADAPTIVE_SPEC",
+ "PRO_SINGULAR_GEN",
+ "SHP_PLASMA_SHIELD",
+ "GRO_XENO_HYBRIDS",
+ "SHP_CONT_BIOADAPT",
+ "SHP_SENT_HULL",
+ "LRN_TIME_MECH",
+ "LRN_STELLAR_TOMOGRAPHY",
+ "SHP_XENTRONIUM_PLATE",
+ "SPY_DETECT_4",
+ "GRO_CYBORG",
+ "GRO_ENERGY_META",
+ "LRN_ENCLAVE_VOID",
+ "CON_NDIM_STRC",
+ "SHP_WEAPON_4_1",
+ "SHP_WEAPON_4_2",
+ "LRN_PSY_DOM",
+ "LRN_ART_BLACK_HOLE",
+ "LRN_DISTRIB_THOUGHT",
+ "PRO_NEUTRONIUM_EXTRACTION",
+ "SHP_ASTEROID_HULLS",
+ "GRO_TERRAFORM",
+ "GRO_GENETIC_MED",
+ "SHP_INTSTEL_LOG",
+ "SPY_STEALTH_1",
+ "CON_CONC_CAMP",
+ "PRO_INDUSTRY_CENTER_III",
+ "SPY_STEALTH_2",
+ "DEF_SYST_DEF_MINE_2",
+ "SHP_WEAPON_4_3",
+ "DEF_SYST_DEF_MINE_3",
+ "SPY_STEALTH_3",
+ "SPY_DETECT_5",
+ "SHP_WEAPON_4_4",
+ "SHP_BLACKSHIELD",
+ "DEF_GARRISON_4",
+ "DEF_DEFENSE_NET_REGEN_2",
+ "SPY_STEALTH_4",
+ "SHP_ENRG_BOUND_MAN",
+ "DEF_PLAN_BARRIER_SHLD_4",
+ "DEF_PLAN_BARRIER_SHLD_5",
+ "GRO_GAIA_TRANS",
+ "CON_ART_PLANET",
+ "SHP_SOLAR_CONT",
+ };
+ const char* oldtechs[] = {
+ "SHP_WEAPON_2",
+ "GRO_PLANET_ECOL",
+ "SHP_WEAPON_3",
+ "SHP_DOMESTIC_MONSTER",
+ "SHP_ORG_HULL",
+ "GRO_SUBTER_HAB",
+ "SHP_WEAPON_5",
+ "LRN_ALGO_ELEGANCE",
+ "LRN_ARTIF_MINDS",
+ "PRO_ROBOTIC_PROD",
+ "SHP_WEAPON_6",
+ "DEF_DEFENSE_NET_1",
+ "PRO_FUSION_GEN",
+ "CON_ENV_ENCAPSUL",
+ "LRN_FORCE_FIELD",
+ "CON_ORBITAL_CON",
+ "PRO_ORBITAL_GEN",
+ "GRO_SYMBIOTIC_BIO",
+ "DEF_GARRISON_1",
+ "GRO_GENETIC_ENG",
+ "GRO_XENO_GENETICS",
+ "SPY_DETECT_2",
+ "SHP_WEAPON_7",
+ "PRO_INDUSTRY_CENTER_I",
+ "DEF_DEFENSE_NET_2",
+ "PRO_SOL_ORB_GEN",
+ "SHP_BASIC_DAM_CONT",
+ "SHP_WEAPON_9",
+ "DEF_GARRISON_2",
+ "CON_METRO_INFRA",
+ "GRO_LIFECYCLE_MAN",
+ "SHP_MULTICELL_CAST",
+ "SHP_ENDOCRINE_SYSTEMS",
+ "SHP_ADV_DAM_CONT",
+ "LRN_QUANT_NET",
+ "DEF_DEFENSE_NET_REGEN_1",
+ "DEF_PLAN_BARRIER_SHLD_1",
+ "SHP_WEAPON_10",
+ "PRO_INDUSTRY_CENTER_II",
+ "SPY_DETECT_3",
+ "SHP_WEAPON_11",
+ "DEF_PLAN_BARRIER_SHLD_2",
+ "LRN_GRAVITONICS",
+ "SHP_REINFORCED_HULL",
+ "CON_CONTGRAV_ARCH",
+ "LRN_PHYS_BRAIN",
+ "LRN_TRANSLING_THT",
+ "PRO_SENTIENT_AUTOMATION",
+ "PRO_EXOBOTS",
+ "DEF_DEFENSE_NET_3",
+ "DEF_SYST_DEF_MINE_1",
+ "DEF_PLAN_BARRIER_SHLD_3",
+ "CON_ORBITAL_HAB",
+ "DEF_GARRISON_3",
+ "SHP_CONT_SYMB",
+ "SHP_MONOCELL_EXP",
+ "SHP_ENDOSYMB_HULL",
+ "PRO_SINGULAR_GEN",
+ "LRN_XENOARCH",
+ "PRO_MICROGRAV_MAN",
+ "SHP_LEAD_PLATE",
+ "GRO_XENO_HYBRIDS",
+ "SHP_ZORTRIUM_PLATE",
+ "SHP_WEAPON_13",
+ "CON_CONC_CAMP",
+ "LRN_TIME_MECH",
+ "LRN_STELLAR_TOMOGRAPHY",
+ "SHP_WEAPON_14",
+ "SPY_DETECT_4",
+ "PRO_NEUTRONIUM_EXTRACTION",
+ "LRN_ENCLAVE_VOID",
+ "LRN_PSY_DOM",
+ "LRN_ART_BLACK_HOLE",
+ "SHP_ASTEROID_HULLS",
+ "GRO_TERRAFORM",
+ "GRO_GENETIC_MED",
+ "SHP_BIOADAPTIVE_SPEC",
+ "SHP_INTSTEL_LOG",
+ "SHP_CONT_BIOADAPT",
+ "SHP_SENT_HULL",
+ "DEF_SYST_DEF_MINE_2",
+ "GRO_CYBORG",
+ "PRO_INDUSTRY_CENTER_III",
+ "SHP_WEAPON_15",
+ "DEF_GARRISON_4",
+ "SPY_STEALTH_1",
+ "DEF_DEFENSE_NET_REGEN_2",
+ "SHP_ENRG_BOUND_MAN",
+ "GRO_GAIA_TRANS",
+ "GRO_ENERGY_META",
+ "CON_ART_PLANET",
+ "LRN_DISTRIB_THOUGHT",
+ "GRO_ENERGY_META",
+ "DEF_SYST_DEF_MINE_3",
+ "DEF_PLAN_BARRIER_SHLD_4",
+ "DEF_PLAN_BARRIER_SHLD_5",
+ "SHP_SOLAR_CONT",
+ "SPY_DETECT_5",
+ "SHP_WEAPON_16",
+ "SHP_WEAPON_17",
+ //"CON_FRC_ENRG_STRC",
+ //"CON_NDIM_STRC",
+ //"CON_FRC_ENRG_CAMO",
+ };
+ std::vector<std::string> techVec(techs,techs+numTechs);
+ if (techVec[numTechs-4] != "GRO_ENERGY_META")
+ Logger().errorStream() << "Error: LoadMyTechs seems to have an incorrect length for my Techs array...";
+ TechManager& manager = GetTechManager();
+ int empireID = HumanClientApp::GetApp()->EmpireID();
+ for (std::vector<std::string>::iterator techIt = techVec.begin(); techIt != techVec.end(); ++techIt) {
+ std::vector<std::string> tech_vec = manager.RecursivePrereqs(*techIt, empireID);
+ tech_vec.push_back(*techIt);
+ AddTechsToQueueSignal(tech_vec, -1);
+ };
+}
Modified: trunk/FreeOrion/python/PythonEmpireWrapper.cpp
===================================================================
--- trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/python/PythonEmpireWrapper.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -85,7 +85,7 @@
std::set<IntPair > laneset;
std::vector<IntPair> retval;
try {
- laneset = empire.SupplyOstructedStarlaneTraversals();
+ laneset = empire.SupplyObstructedStarlaneTraversals();
for (std::set<std::pair<int, int> >::const_iterator it = laneset.begin(); it != laneset.end(); ++it)
{retval.push_back(*it); }
return retval;
@@ -295,7 +295,7 @@
return_internal_reference<>(),
boost::mpl::vector<const SitRepEntry&, const Empire&, int>()
))
- //.add_property("obstructedStarlanes", make_function(&Empire::SupplyOstructedStarlaneTraversals, return_value_policy<return_by_value>()))
+ //.add_property("obstructedStarlanes", make_function(&Empire::SupplyObstructedStarlaneTraversals, return_value_policy<return_by_value>()))
.def("obstructedStarlanes", make_function(obstructedStarlanesFunc,
return_value_policy<return_by_value>(),
boost::mpl::vector<std::vector<IntPair>, const Empire&>()
Modified: trunk/FreeOrion/server/ServerApp.cpp
===================================================================
--- trunk/FreeOrion/server/ServerApp.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/server/ServerApp.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -1605,7 +1605,7 @@
// update system ownership after combat. may be necessary if the
- // combat caused planets to change ownership. Also update fleet movement blockade restrictions
+ // combat caused planets to change ownership.
if (System* system = GetSystem(combat_info.system_id)) {
// ensure all participants get updates on system. this ensures
// that an empire who lose all objects in the system still
@@ -1613,21 +1613,6 @@
for (std::set<int>::const_iterator empire_it = combat_info.empire_ids.begin();
empire_it != combat_info.empire_ids.end(); ++empire_it)
{ universe.EmpireKnownObjects(*empire_it).CopyObject(system, ALL_EMPIRES); }
-
- //update fleet movement blockade restrictions
- std::map<int,bool> empires_blockaded;
- std::vector<int> system_fleet_ids = system->FindObjectIDs<Fleet>();
- for (std::vector<int>::const_iterator fleet_it = system_fleet_ids.begin(); fleet_it != system_fleet_ids.end(); ++fleet_it) {
- Fleet* fleet = GetFleet(*fleet_it);
- if (!fleet || fleet->ArrivalStarlane() == combat_info.system_id)
- continue;
- if (empires_blockaded.find(fleet->Owner()) == empires_blockaded.end())
- empires_blockaded[ fleet->Owner() ] = fleet->BlockadedAtSystem(combat_info.system_id, false);
- if (!empires_blockaded[ fleet->Owner() ]) {
- fleet->SetArrivalStarlane(combat_info.system_id);
- fleet->CalculateRoute(); //TODO: double check if this is still necessary
- }
- }
}
}
}
@@ -2300,6 +2285,43 @@
CleanupSystemCombatInfo(combats);
}
+void ServerApp::UpdateMonsterTravelRestrictions() {
+ //std::vector<Fleet*> all_fleets = m_universe.Objects().FindObjects<Fleet>;
+ const std::vector<System*> systems = m_universe.Objects().FindObjects<System>();
+ for (std::vector<System*>::const_iterator sys_it = systems.begin(); sys_it!=systems.end(); sys_it++) {
+ const System* system = *sys_it;
+ std::vector<int> fleet_ids = system->FindObjectIDs<Fleet>();
+ bool unrestricted_monsters_present = false;
+ bool unrestricted_empires_present = false;
+ std::vector<int> restricted_monsters;
+ for (std::vector<int>::iterator fleet_it = fleet_ids.begin(); fleet_it != fleet_ids.end(); fleet_it++) {
+ const Fleet* fleet = GetFleet(*fleet_it);
+ // will not require visibility for empires to block clearing of monster travel restrictions
+ // unrestricted lane access (i.e, (fleet->ArrivalStarlane() == system->ID()) ) is used as a proxy for
+ // order of arrival -- if an enemy has unrestricted lane access and you don't, they must have arrived
+ // before you, or be in cahoots with someone who did.
+ bool unrestricted = (fleet->ArrivalStarlane() == system->ID()) && fleet->Aggressive() && fleet->HasArmedShips() ;
+ if (fleet->Unowned()) {
+ if (unrestricted)
+ unrestricted_monsters_present = true;
+ else
+ restricted_monsters.push_back(*fleet_it);
+ } else if (unrestricted) {
+ unrestricted_empires_present = true;
+ }
+ }
+ if (unrestricted_monsters_present || !unrestricted_empires_present) {
+ for (std::vector<int>::iterator monster_it = restricted_monsters.begin();
+ monster_it != restricted_monsters.end(); monster_it++)
+ {
+ Fleet* monster_fleet = GetFleet(*monster_it);
+ // even if it was a diff test that made monster restricted, we will set arrival lane
+ monster_fleet->SetArrivalStarlane(monster_fleet->SystemID());
+ }
+ }
+ }
+}
+
void ServerApp::PostCombatProcessTurns() {
EmpireManager& empires = Empires();
ObjectMap& objects = m_universe.Objects();
@@ -2360,6 +2382,16 @@
empire->UpdateResourcePools(); // determines how much of each resources is available in each resource sharing group
}
+ UpdateMonsterTravelRestrictions();
+ // now update travel restrictions for empire fleets
+ for (EmpireManager::iterator it = empires.begin(); it != empires.end(); ++it) {
+ if (!empires.Eliminated(it->first)) {
+ Empire* empire = it->second;
+ empire->UpdateAvailableLanes();
+ empire->UpdateUnobstructedFleets(); // must be done after *all* noneliminated empires have updated their unobstructed systems
+ }
+ }
+
if (GetOptionsDB().Get<bool>("verbose-logging")) {
Logger().debugStream() << "!!!!!!!!!!!!!!!!!!!!!!AFTER UPDATING RESOURCE POOLS AND SUPPLY STUFF";
Logger().debugStream() << objects.Dump();
Modified: trunk/FreeOrion/server/ServerApp.h
===================================================================
--- trunk/FreeOrion/server/ServerApp.h 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/server/ServerApp.h 2013-06-11 07:59:03 UTC (rev 6140)
@@ -109,6 +109,10 @@
* updating the universe after the results are available. */
void ProcessCombats();
+ /** Used post combat, to selectively clear the m_arrival_starlane flag of monsters
+ * so that they can impose blockades */
+ void UpdateMonsterTravelRestrictions();
+
/** Determines resource and supply distribution pathes and connections,
* updates research, production, trade spending,
* does population growth, updates current turn number, checks for
Modified: trunk/FreeOrion/universe/Fleet.cpp
===================================================================
--- trunk/FreeOrion/universe/Fleet.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/universe/Fleet.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -130,9 +130,11 @@
std::stringstream os;
os << UniverseObject::Dump();
os << ( m_aggressive ? " agressive" : " passive")
+ << " cur system: " << SystemID()
<< " moving to: " << m_moving_to
<< " prev system: " << m_prev_system
<< " next system: " << m_next_system
+ << " arrival lane: " << m_arrival_starlane
<< " ships: ";
for (ShipIDSet::const_iterator it = m_ships.begin(); it != m_ships.end();) {
int ship_id = *it;
@@ -241,8 +243,12 @@
bool isPostBlockade=false;
if (cur_system) {
- if (flag_blockades && next_system->ID() != m_arrival_starlane) {
- if (BlockadedAtSystem(cur_system->ID())){
+ //Logger().debugStream() << "Fleet::MovePath starting in system "<< SystemID();
+ if (flag_blockades && next_system->ID() != m_arrival_starlane &&
+ (unobstructed_systems.find(cur_system->ID()) == unobstructed_systems.end()))
+ {
+ //Logger().debugStream() << "Fleet::MovePath checking blockade from "<< cur_system->ID() << " to "<< next_system->ID();
+ if (BlockadedAtSystem(cur_system->ID(), next_system->ID())){
// blockade debug logging
//Logger().debugStream() << "Fleet::MovePath finds system " <<cur_system->Name() << " (" <<cur_system->ID() <<
// ") blockaded for fleet " << this->Name();
@@ -364,17 +370,23 @@
//Logger().debugStream() << " ... arrived at system: " << cur_system->Name();
- bool clearExit = cur_system->ID() == m_arrival_starlane; //just half the test for the moment
+ bool clear_exit = cur_system->ID() == m_arrival_starlane; //just part of the test for the moment
// attempt to get next system on route, to update next system. if new current
// system is the end of the route, abort.
++route_it;
if (route_it != route.end()) {
// update next system on route and distance to it from current position
next_system = GetEmpireKnownSystem(*route_it, owner);
- clearExit = clearExit || (next_system && next_system->ID() == m_arrival_starlane);
+ if (next_system) {
+ //Logger().debugStream() << "Fleet::MovePath checking unrestriced lane travel";
+ clear_exit = clear_exit || (next_system && next_system->ID() == m_arrival_starlane) ||
+ (empire && empire->UnrestrictedLaneTravel(cur_system->ID(), next_system->ID()));
+ }
}
- if (flag_blockades && !clearExit) {
- if (BlockadedAtSystem(cur_system->ID(), false)) {
+ if (flag_blockades && !clear_exit) {
+ //Logger().debugStream() << "Fleet::MovePath checking blockades at system "<<cur_system->Name() << " ("<<cur_system->ID() <<
+ // ") for fleet " << this->Name() <<" travelling to system "<< (*route_it);
+ if (BlockadedAtSystem(cur_system->ID(), next_system->ID())) {
// blockade debug logging
//Logger().debugStream() << "Fleet::MovePath finds system "<<cur_system->Name() << " ("<<cur_system->ID() <<
// ") blockaded for fleet " << this->Name();
@@ -399,9 +411,7 @@
// if new position is an obstructed system, must end turn here
// on client side, if have stale info on cur_system it may appear blockaded even if not actually obstructed,
// and so will force a stop in that situation
- if ((cur_system && unobstructed_systems.find(cur_system->ID()) == unobstructed_systems.end()) ||
- (cur_system && BlockadedAtSystem(cur_system->ID())) )
- {
+ if (cur_system && (unobstructed_systems.find(cur_system->ID()) == unobstructed_systems.end())) {
turn_dist_remaining = 0.0;
end_turn_at_cur_position = true;
}
@@ -450,6 +460,7 @@
(prev_system ? prev_system->ID() : INVALID_OBJECT_ID),
(next_system ? next_system->ID() : INVALID_OBJECT_ID), isPostBlockade);
retval.push_back(final_pos);
+ //Logger().debugStream() << "Fleet::MovePath for fleet " << this->Name()<<" id "<<this->ID()<<" is complete";
return retval;
}
@@ -630,6 +641,7 @@
{ return visitor.Visit(const_cast<Fleet* const>(this)); }
void Fleet::SetRoute(const std::list<int>& route) {
+ //Logger().debugStream() << "Fleet::SetRoute() ";
if (route.empty())
throw std::invalid_argument("Fleet::SetRoute() : Attempted to set an empty route.");
@@ -648,6 +660,7 @@
m_travel_distance = 0.0;
for (std::list<int>::const_iterator it = m_travel_route.begin(); it != m_travel_route.end(); ++it) {
std::list<int>::const_iterator next_it = it; ++next_it;
+ //Logger().debugStream() << "Fleet::SetRoute() new route has system id " << *it;
if (next_it == m_travel_route.end())
break; // current system is the last on the route, so don't need to add any additional distance.
@@ -674,7 +687,7 @@
if (SystemID() != INVALID_OBJECT_ID && SystemID() == m_travel_route.back()) {
m_moving_to = INVALID_OBJECT_ID;
m_next_system = INVALID_OBJECT_ID;
- m_prev_system = INVALID_OBJECT_ID;
+ //m_prev_system = INVALID_OBJECT_ID;
} else {
// if we're already moving, add in the distance from where we are to the first system in the route
@@ -805,6 +818,9 @@
//Logger().debugStream() << "Fleet::MovementPhase this: " << this->Name() << " id: " << this->ID();
Empire* empire = Empires().Lookup(this->Owner());
+ std::set<int> supply_unobstructed_systems;
+ if (empire)
+ supply_unobstructed_systems.insert(empire->SupplyUnobstructedSystems().begin(), empire->SupplyUnobstructedSystems().end());
// if owner of fleet can resupply ships at the location of this fleet, then
// resupply all ships in this fleet
@@ -826,29 +842,37 @@
if (next_it != move_path.end())
++next_it;
+ //Logger().debugStream() << "Fleet::MovementPhase for Fleet "<< ID() << " with m_arrival_lane "<<m_arrival_starlane<< " at system ("<<SystemID()<<")";
// is the ship stuck in a system for a whole turn?
if (current_system) {
///update m_arrival_starlane if no blockade, if needed
// blockade debug logging
//Logger().debugStream() << "Fleet::MovementPhase checking blockade for Fleet "<< ID() << " with m_arrival_lane "<<m_arrival_starlane<< " at current_system " << current_system->Name() << "("<<SystemID()<<")";
- if (!BlockadedAtSystem(SystemID()) && m_arrival_starlane != SystemID() ) {
- //Logger().debugStream() << "Fleet::MovementPhase clearing m_arrival_starlane for Fleet "<< ID() << " at current_system " << current_system->Name() << "("<<SystemID()<<")";
- m_arrival_starlane = SystemID();//allows departure via any starlane
+ if (supply_unobstructed_systems.find(SystemID()) != supply_unobstructed_systems.end()) {
+ //Logger().debugStream() << "Fleet::MovementPhase clearing m_arrival_starlane for Fleet "<< ID() << " at current_system " << current_system->Name() << "("<<SystemID()<<")";
+ m_arrival_starlane = SystemID();//allows departure via any starlane
}
-
// in a system. if there is no system after the current one in the
// path, or the current and next nodes have the same system id, that
// is an actual system, or if blockaded from intended path, then won't be moving this turn.
- if ((next_it == move_path.end()) ||
- ((m_arrival_starlane != SystemID()) && ( (next_it->object_id != INVALID_OBJECT_ID && next_it->object_id != m_arrival_starlane) ||
- (next_it->lane_end_id != INVALID_OBJECT_ID && next_it->lane_end_id != m_arrival_starlane) ) ) ||
- (it->object_id != INVALID_OBJECT_ID && it->object_id == next_it->object_id) )
- {
- if ((m_arrival_starlane != SystemID()) && (m_arrival_starlane != next_it->lane_end_id)) {
- //Logger().debugStream() << "Fleet::MovementPhase delaying Fleet "<< ID() << " at system " << current_system->Name() <<
- // "("<<SystemID()<<") with next system id " << next_it->object_id << " and m_arrival_starlane "<< m_arrival_starlane;
+ bool stopped = false;
+ if (next_it == move_path.end()) {
+ stopped = true;
+ } else if (it->object_id != INVALID_OBJECT_ID && it->object_id == next_it->object_id) {
+ stopped = true;
+ //Logger().debugStream() << "Fleet::MovementPhase stopping due to doubled system at start of path";
+ } else if (m_arrival_starlane != SystemID()) {
+ int next_sys_id;
+ if (next_it->object_id != INVALID_OBJECT_ID) {
+ next_sys_id = next_it->object_id;
+ } else {
+ next_sys_id = next_it->lane_end_id;
}
+ stopped = BlockadedAtSystem(SystemID(), next_sys_id);
+ }
+
+ if (stopped) {
// fuel regeneration for ships in stationary fleet
if (this->FinalDestinationID() == INVALID_OBJECT_ID ||
this->FinalDestinationID() == this->SystemID())
@@ -862,6 +886,9 @@
}
}
return;
+ } else {
+ m_arrival_starlane = SystemID();
+ m_prev_system = SystemID();
}
}
@@ -893,8 +920,10 @@
if (system) {
// node is a system. explore system for all owners of this fleet
- if (empire)
+ if (empire) {
empire->AddExploredSystem(it->object_id);
+ empire->RecordPendingLaneUpdate(it->object_id, m_prev_system); // specifies the lane from it->object_id back to m_prev_system is available
+ }
m_prev_system = system->ID(); // passing a system, so update previous system of this fleet
@@ -917,7 +946,7 @@
current_system = system;
// blockade debug logging
//Logger().debugStream() << "Fleet::MovementPhase checking blockade for Fleet "<< ID() << " with m_arrival_lane "<<m_arrival_starlane<< " at next stop node system " << current_system->Name() << "("<<SystemID()<<")";
- if (!BlockadedAtSystem(system->SystemID())) {
+ if (supply_unobstructed_systems.find(SystemID()) != supply_unobstructed_systems.end()) {
m_arrival_starlane = SystemID();//allows departure via any starlane
//Logger().debugStream() << "Fleet::MovementPhase clearing m_arrival_starlane for Fleet "<< ID() << " at (next stop node) system " << system->Name() << "("<<system->ID()<<")";
}
@@ -1129,29 +1158,43 @@
}
}
-bool Fleet::BlockadedAtSystem(int systemID, bool preCombat) const {
+bool Fleet::BlockadedAtSystem(int start_system_id, int dest_system_id) const {
/** If a newly arrived fleet joins a non-blockaded fleet of the same empire (perhaps should include allies?)
* already at the system, the newly arrived fleet will not be blockaded. Additionally,
* since fleets are blockade-checked at movement phase and also postcombat, the following tests mean
* that post-compbat, this fleet will be blockaded iff it was blockaded pre-combat AND there are armed
- * aggressive enemies surviving in system post-combat which can detect this fleet **/
+ * aggressive enemies surviving in system post-combat which can detect this fleet. Fleets arriving at the
+ * same time do not blockade each other. Unrestricted lane access (i.e, (fleet->ArrivalStarlane() == system->ID()) )
+ * is used as a proxy for order of arrival -- if an enemy has unrestricted l*ane access and you don't,
+ * they must have arrived before you, or be in cahoots with someone who did. */
- return false;
- /*
-
- if (m_arrival_starlane == systemID) {
- Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " has cleared blockade flag for system (" << systemID << ")";
+ if (m_arrival_starlane == start_system_id) {
+ //Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " has cleared blockade flag for system (" << start_system_id << ")";
return false;
}
+ bool not_yet_in_system = SystemID() != start_system_id;
// find which empires have blockading aggressive armed ships in system; fleets that just arrived do not
// blockade by themselves, but may reinforce a preexisting blockade, and may possibly contribute to detection
- System* current_system = GetSystem(systemID);
+ System* current_system = GetSystem(start_system_id);
if (!current_system) {
- Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " considering system (" << systemID << ") but can't retrieve system copy";
+ Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " considering system (" << start_system_id << ") but can't retrieve system copy";
return false;
}
+ EmpireManager& manager = Empires();
+ const Empire* empire = manager.Lookup(this->Owner());
+ if (empire) {
+ std::set<int> unobstructed_systems = empire->SupplyUnobstructedSystems();
+ if (unobstructed_systems.find(start_system_id) != unobstructed_systems.end())
+ return false;
+ if (empire->UnrestrictedLaneTravel(start_system_id, dest_system_id)) {
+ return false;
+ } else {
+ //Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " considering travel from system (" << start_system_id << ") to system (" << dest_system_id << ")";
+ }
+ }
+
float lowestShipStealth = 99999;
for (std::set<int>::const_iterator ship_it = this->ShipIDs().begin(); ship_it != this->ShipIDs().end(); ++ship_it) {
const Ship* ship = GetShip(*ship_it);
@@ -1160,8 +1203,6 @@
}
std::vector<int> system_fleet_ids = current_system->FindObjectIDs<Fleet>();
- Logger().debugStream() << "Fleet::BlockadedAtSystem fleet " << ID() << " considers system " << current_system->Name() << " (" <<
- systemID << ") with " << system_fleet_ids.size() << " total fleets apparently present" ;
float monsterDetection = 0;
for (std::vector<int>::const_iterator fleet_it = system_fleet_ids.begin(); fleet_it != system_fleet_ids.end(); ++fleet_it) {
@@ -1169,100 +1210,44 @@
if (!fleet->Unowned())
continue;
for (std::set<int>::const_iterator ship_it = fleet->ShipIDs().begin(); ship_it != fleet->ShipIDs().end(); ++ship_it) {
- const Ship* ship = GetShip(*ship_it);
- if ((ship) && ship->CurrentMeterValue(METER_DETECTION) >= monsterDetection)
- monsterDetection = ship->CurrentMeterValue(METER_DETECTION);
+ if (const Ship* ship = GetShip(*ship_it)){
+ float curDetect = ship->CurrentMeterValue(METER_DETECTION);
+ if (curDetect >= monsterDetection)
+ monsterDetection = curDetect;
+ }
}
}
bool canBeBlockaded = false;
- int tryingToLeave = 0;
- int othersPresent = 0;
- int nonaggressive = 0;
- int unarmed = 0;
- int newArrival = 0;
- int notAtWar = 0;
- int cantSee = 0;
- int blockadedBy = INVALID_OBJECT_ID;
- EmpireManager& manager = Empires();
for (std::vector<int>::const_iterator fleet_it = system_fleet_ids.begin(); fleet_it != system_fleet_ids.end(); ++fleet_it) {
const Fleet* fleet = GetFleet(*fleet_it);
- if (!fleet)
+ if (!fleet || (fleet->NextSystemID() != INVALID_OBJECT_ID)) //fleets trying to leave this turn can't blockade pre-combat.
continue;
- bool justArrived = fleet->ArrivedThisTurn() && (this->Unowned() || (fleet->Name() != "" ) || // Name() != "" iff current app is server, or owner client
- (GetUniverse().GetObjectVisibilityByEmpire(*fleet_it, this->Owner()) >= VIS_BASIC_VISIBILITY ) ); //keep consistent with Fleet::Copy()
- int empireDetection = 0;
- if (!fleet->Unowned()) {
- empireDetection = manager.Lookup(fleet->Owner())->GetMeter("METER_DETECTION_STRENGTH")->Current();
- } else {
- empireDetection = monsterDetection;
- }
- if ( preCombat && (fleet->NextSystemID() != INVALID_OBJECT_ID) ) { //fleets trying to leave this turn can't blockade pre-combat.
- if (fleet->Owner() != this->Owner()) {
- Logger().debugStream() << "Fleet::BlockadedAtSystem other fleet " << fleet->ID() << " trying to leave to system (" << fleet->NextSystemID()<<")";
- tryingToLeave++;
- othersPresent++;
- }
- continue;
- }
+ bool unrestricted = (fleet->m_arrival_starlane == start_system_id);
if (fleet->Owner() == this->Owner()) {
- if (fleet->m_arrival_starlane == systemID) { // perhaps should consider allies
- Logger().debugStream() << "Fleet::BlockadedAtSystem Fleet "<< ID() << " not blockaded at system " << current_system->Name() <<
- "(" << systemID << ") due to non-blockaded fleet (" << fleet->ID() << ") already present";
+ if (unrestricted) // perhaps should consider allies
return false;
- }
continue;
}
- bool diplo = ( Empires().GetDiplomaticStatus(this->Owner(), fleet->Owner()) == DIPLO_WAR );
- bool canSee = empireDetection >= lowestShipStealth;
- Logger().debugStream() << "Fleet::BlockadedAtSystem ... considering Fleet " << ID() << "noting other Fleet "<< fleet->ID() <<
- ", aggression " << fleet->Aggressive() << ", armed " << fleet->HasArmedShips() << ", justArrived " <<
- fleet->ArrivedThisTurn() << ", apparently just_arrived " << justArrived << ", diplo-war " <<
- diplo << ", canSee " << canSee;
- if (!canSee)
- Logger().debugStream() << "Fleet::BlockadedAtSystem ... other fleet w/ detection " << empireDetection <<
- " can't see this fleet w/ stealth " << lowestShipStealth;
-
- othersPresent++;
- if ((fleet->Aggressive() || fleet->Unowned() ) && fleet->HasArmedShips() && (!preCombat || !justArrived)) {
- if ((this->Unowned() || fleet->Unowned() || ( Empires().GetDiplomaticStatus(this->Owner(), fleet->Owner()) == DIPLO_WAR )) && canSee ) {
- canBeBlockaded = true; // don't exit early here, because blockade may yet be thwarted by ownership & presence check above
- blockadedBy = (*fleet_it);
- } else if( !this->Unowned() && !fleet->Unowned() &&
- ( Empires().GetDiplomaticStatus(this->Owner(), fleet->Owner()) != DIPLO_WAR ) )
- {
- notAtWar++;
- } else if ( !canSee ) {
- cantSee++;
- }
- } else if (!(fleet->Aggressive() || fleet->Unowned())) {
- nonaggressive++;
- } else if (!fleet->HasArmedShips()) {
- unarmed ++;
- } else if ( (preCombat && justArrived)) {
- newArrival++;
+ bool can_see;
+ if (!fleet->Unowned()) {
+ can_see = (manager.Lookup(fleet->Owner())->GetMeter("METER_DETECTION_STRENGTH")->Current() >= lowestShipStealth);
+ } else {
+ can_see = (monsterDetection >= lowestShipStealth);
}
+ bool at_war = Unowned() || fleet->Unowned() || Empires().GetDiplomaticStatus(this->Owner(), fleet->Owner()) == DIPLO_WAR ;
+ bool aggressive = (fleet->Aggressive() || fleet->Unowned() );
+
+ if (aggressive && fleet->HasArmedShips() && at_war && can_see && (unrestricted || not_yet_in_system))
+ canBeBlockaded = true; // don't exit early here, because blockade may yet be thwarted by ownership & presence check above
}
if (canBeBlockaded) {
- int blocker_vis = int( GetUniverse().GetObjectVisibilityByEmpire(blockadedBy, this->Owner()) );
- Logger().debugStream() << "Fleet::BlockadedAtSystem Fleet "<< ID() << " with m_arrival_lane "<<m_arrival_starlane<<
- " blockaded at system " << current_system->Name() << "("<<systemID<<") by enemy fleet ("<< (blockadedBy) <<
- ") for which this fleet has visibility("<<blocker_vis<<"), next travel destinatino is system (" << NextSystemID();
return true;
}
- if (othersPresent||tryingToLeave) {
- Logger().debugStream() << "Fleet::BlockadedAtSystem precombat (" << preCombat << ") Fleet " << ID() << " with m_arrival_lane " <<
- m_arrival_starlane << " not blockaded at system " << current_system->Name() << "(" << systemID << ") despite " <<
- othersPresent << " other fleets present, " << nonaggressive << " nonaggressive, " << unarmed << " unarmed, " <<
- newArrival << " new arrivals, " << notAtWar << " not at war, " << cantSee << " can't see present fleet, " <<
- tryingToLeave << " trying to leave system pre-combat.";
- } else {
- Logger().debugStream() << "Fleet::BlockadedAtSystem Fleet "<< ID() << " finds system " << current_system->Name() << " empty";
- }
return false;
- */
-}
+}
+
double Fleet::Speed() const {
if (m_ships.empty())
return 0.0;
Modified: trunk/FreeOrion/universe/Fleet.h
===================================================================
--- trunk/FreeOrion/universe/Fleet.h 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/universe/Fleet.h 2013-06-11 07:59:03 UTC (rev 6140)
@@ -84,7 +84,7 @@
int FinalDestinationID() const { return m_moving_to; } ///< Returns ID of system that this fleet is moving to.
int PreviousSystemID() const { return m_prev_system; } ///< Returns ID of system that this fleet is moving away from as it moves to its destination.
int NextSystemID() const { return m_next_system; } ///< Returns ID of system that this fleet is moving to next as it moves to its destination.
- bool BlockadedAtSystem(int systemID, bool preCombat = true) const; ///< returns true iff this fleet's movement would be blockaded at system.
+ bool BlockadedAtSystem(int start_system_id, int dest_system_id) const; ///< returns true iff this fleet's movement would be blockaded at system.
double Speed() const; ///< Returns speed of fleet. (Should be equal to speed of slowest ship in fleet, unless in future the calculation of fleet speed changes.)
bool CanChangeDirectionEnRoute() const { return false; } ///< Returns true iff this fleet can change its direction while in interstellar space.
bool HasMonsters() const; ///< returns true iff this fleet contains monster ships.
Modified: trunk/FreeOrion/util/SerializeEmpire.cpp
===================================================================
--- trunk/FreeOrion/util/SerializeEmpire.cpp 2013-06-10 16:40:33 UTC (rev 6139)
+++ trunk/FreeOrion/util/SerializeEmpire.cpp 2013-06-11 07:59:03 UTC (rev 6140)
@@ -93,6 +93,7 @@
& BOOST_SERIALIZATION_NVP(m_supply_unobstructed_systems)
& BOOST_SERIALIZATION_NVP(m_supply_starlane_traversals)
& BOOST_SERIALIZATION_NVP(m_supply_starlane_obstructed_traversals)
+ & BOOST_SERIALIZATION_NVP(m_available_system_exit_lanes)
& BOOST_SERIALIZATION_NVP(m_fleet_supplyable_system_ids)
& BOOST_SERIALIZATION_NVP(m_resource_supply_groups);
|