Skip to content

Commit 6db0673

Browse files
authored
Merge pull request #1889 from Noseey/pathfinding_rejects
Pathfinding: reject unconnected buildings / construction sites in specific scenarios
2 parents e6489dc + d7cf2c5 commit 6db0673

4 files changed

Lines changed: 43 additions & 1 deletion

File tree

libs/s25main/GamePlayer.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,13 @@ void GamePlayer::ToolOrderProcessed(Tool tool)
804804

805805
bool GamePlayer::FindWarehouseForJob(const Job job, noRoadNode& goal) const
806806
{
807+
// Optimization: return early if building is isolated
808+
if(goal.GetType() == NodalObjectType::Building || goal.GetType() == NodalObjectType::Buildingsite)
809+
{
810+
if(!static_cast<noBaseBuilding&>(goal).IsConnected())
811+
return false;
812+
}
813+
807814
nobBaseWarehouse* wh = FindWarehouse(goal, FW::HasFigure(job, true), false, false);
808815

809816
if(wh)
@@ -1026,6 +1033,10 @@ noBaseBuilding* GamePlayer::FindClientForWare(const Ware& ware)
10261033
// Bei Baustellen die Extraliste abfragen
10271034
for(noBuildingSite* bldSite : buildings.GetBuildingSites())
10281035
{
1036+
// Optimization: Ignore if unconnected
1037+
if(!bldSite->IsConnected())
1038+
continue;
1039+
10291040
unsigned points = bldSite->CalcDistributionPoints(gt);
10301041
if(!points)
10311042
continue;
@@ -1039,6 +1050,10 @@ noBaseBuilding* GamePlayer::FindClientForWare(const Ware& ware)
10391050
// Für übrige Gebäude
10401051
for(nobUsual* bld : buildings.GetBuildings(bldType))
10411052
{
1053+
// Optimization: Ignore if unconnected
1054+
if(!bld->IsConnected())
1055+
continue;
1056+
10421057
unsigned points = bld->CalcDistributionPoints(gt);
10431058
if(!points)
10441059
continue; // Ware not needed
@@ -1140,12 +1155,16 @@ nobBaseMilitary* GamePlayer::FindClientForCoin(const Ware& ware) const
11401155
// Militärgebäude durchgehen
11411156
for(nobMilitary* milBld : buildings.GetMilitaryBuildings())
11421157
{
1143-
unsigned way_points;
1158+
// Optimization: Ignore if unconnected
1159+
if(!milBld->IsConnected())
1160+
continue;
11441161

11451162
points = milBld->CalcCoinsPoints();
11461163
// Wenn 0, will er gar keine Münzen (Goldzufuhr gestoppt)
11471164
if(points)
11481165
{
1166+
unsigned way_points;
1167+
11491168
// Weg dorthin berechnen
11501169
if(world.FindPathForWareOnRoads(*ware.GetLocation(), *milBld, &way_points) != RoadPathDirection::None)
11511170
{

libs/s25main/buildings/noBaseBuilding.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,23 @@ MapPoint noBaseBuilding::GetFlagPos() const
207207
return world->GetNeighbour(pos, Direction::SouthEast);
208208
}
209209

210+
bool noBaseBuilding::IsConnected() const
211+
{
212+
// Harbors are always considered connected via sea
213+
if(GetBuildingType() == BuildingType::HarborBuilding)
214+
return true;
215+
216+
const helpers::EnumArray<RoadSegment*, Direction>& routes = GetFlag()->getRoutes();
217+
// Check paths in all directions except back to building
218+
for(const auto dir : helpers::EnumRange<Direction>{})
219+
{
220+
if(dir != Direction::NorthWest && routes[dir])
221+
return true;
222+
}
223+
224+
return false;
225+
}
226+
210227
void noBaseBuilding::WareNotNeeded(Ware* ware)
211228
{
212229
if(!ware)

libs/s25main/buildings/noBaseBuilding.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class noBaseBuilding : public noRoadNode
5757
noFlag* GetFlag() const;
5858
/// Same as GetFlag()->GetPos()
5959
MapPoint GetFlagPos() const;
60+
/// Is the building (flag) connected to anything?
61+
bool IsConnected() const;
6062

6163
/// Return the offset of the door, which is also where people disappear into the building, the builder is building
6264
/// and the wares are lying

libs/s25main/buildings/noBuildingSite.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ void noBuildingSite::OrderConstructionMaterial()
148148
if(state == BuildingSiteState::Planing)
149149
return;
150150

151+
// Optimization: return early if building is isolated
152+
if(!IsConnected())
153+
return;
154+
151155
// Bretter
152156
GamePlayer& owner = world->GetPlayer(player);
153157
for(int i = used_boards + boards + ordered_boards.size(); i < BUILDING_COSTS[bldType_].boards; ++i)

0 commit comments

Comments
 (0)