• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 22583127433

02 Mar 2026 03:35PM UTC coverage: 50.316%. First build
22583127433

Pull #1895

github

web-flow
Merge ce0296c39 into 8a6c9b6f2
Pull Request #1895: Ships: Fix crash when doing expedition between adjacent harbor places

5 of 10 new or added lines in 2 files covered. (50.0%)

23034 of 45779 relevant lines covered (50.32%)

43371.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.76
/libs/s25main/Pathfinding.cpp
1
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "GamePlayer.h"
6
#include "helpers/EnumRange.h"
7
#include "pathfinding/FreePathFinder.h"
8
#include "pathfinding/FreePathFinderImpl.h"
9
#include "pathfinding/PathConditionHuman.h"
10
#include "pathfinding/PathConditionShip.h"
11
#include "pathfinding/PathConditionTrade.h"
12
#include "pathfinding/RoadPathFinder.h"
13
#include "world/GameWorld.h"
14
#include "gameTypes/ShipDirection.h"
15
#include "gameData/GameConsts.h"
16

17
/// Findet einen Weg für Figuren
18
helpers::OptionalEnum<Direction> GameWorldBase::FindHumanPath(const MapPoint start, const MapPoint dest,
5,495✔
19
                                                              const unsigned max_route, const bool random_route,
20
                                                              unsigned* length, std::vector<Direction>* route) const
21
{
22
    Direction first_dir{};
5,495✔
23
    if(GetFreePathFinder().FindPath(start, dest, random_route, max_route, route, length, &first_dir,
10,990✔
24
                                    PathConditionHuman(*this)))
10,990✔
25
        return first_dir;
4,791✔
26
    else
27
        return boost::none;
704✔
28
}
29

30
/// Wegfindung für Menschen im Straßennetz
31
RoadPathDirection GameWorld::FindHumanPathOnRoads(const noRoadNode& start, const noRoadNode& goal, unsigned* length,
350✔
32
                                                  MapPoint* firstPt, const RoadSegment* const forbidden)
33
{
34
    RoadPathDirection first_dir;
35
    if(GetRoadPathFinder().FindPath(start, goal, false, std::numeric_limits<unsigned>::max(), forbidden, length,
350✔
36
                                    &first_dir, firstPt))
37
        return first_dir;
349✔
38
    else
39
        return RoadPathDirection::None;
1✔
40
}
41

42
/// Wegfindung für Waren im Straßennetz
43
RoadPathDirection GameWorld::FindPathForWareOnRoads(const noRoadNode& start, const noRoadNode& goal, unsigned* length,
318✔
44
                                                    MapPoint* firstPt, unsigned max)
45
{
46
    RoadPathDirection first_dir;
47
    if(GetRoadPathFinder().FindPath(start, goal, true, max, nullptr, length, &first_dir, firstPt))
318✔
48
        return first_dir;
314✔
49
    else
50
        return RoadPathDirection::None;
4✔
51
}
52

53
bool GameWorldBase::FindShipPathToHarbor(const MapPoint start, unsigned harborId, unsigned seaId,
23✔
54
                                         std::vector<Direction>* route, unsigned* length)
55
{
56
    // Find the distance to the furthest harbor from the target harbor and take that as maximum
57
    unsigned maxDistance = 0;
23✔
58

59
    for(const auto dir : helpers::EnumRange<ShipDirection>{})
368✔
60
    {
61
        const std::vector<HarborPos::Neighbor>& neighbors = GetHarborNeighbors(harborId, dir);
138✔
62
        for(const HarborPos::Neighbor& neighbor : neighbors)
207✔
63
        {
64
            if(IsHarborAtSea(neighbor.id, seaId) && neighbor.distance > maxDistance)
69✔
65
                maxDistance = neighbor.distance;
44✔
66
        }
67
    }
68
    // Add a few fields reserve
69
    maxDistance += 6;
23✔
70

71
    MapPoint harborPoint = GetCoastalPoint(harborId, seaId);
23✔
72

73
    // already arrived?
74
    if(start == harborPoint)
23✔
75
    {
NEW
76
        if(length)
×
NEW
77
            *length = 0;
×
NEW
78
        if(route)
×
NEW
79
            route->clear();
×
NEW
80
        return true;
×
81
    }
82

83
    return FindShipPath(start, harborPoint, maxDistance, route, length);
23✔
84
}
85

86
bool GameWorldBase::FindShipPath(const MapPoint start, const MapPoint dest, unsigned maxDistance,
117✔
87
                                 std::vector<Direction>* route, unsigned* length)
88
{
89
    return GetFreePathFinder().FindPath(start, dest, true, maxDistance, route, length, nullptr,
234✔
90
                                        PathConditionShip(*this));
234✔
91
}
92

93
/// Prüft, ob eine Schiffsroute noch Gültigkeit hat
94
bool GameWorld::CheckShipRoute(const MapPoint start, const std::vector<Direction>& route, const unsigned pos,
373✔
95
                               MapPoint* dest)
96
{
97
    return GetFreePathFinder().CheckRoute(start, route, pos, PathConditionShip(*this), dest);
373✔
98
}
99

100
/// Find a route for trade caravanes
101
helpers::OptionalEnum<Direction> GameWorld::FindTradePath(const MapPoint start, const MapPoint dest,
36✔
102
                                                          unsigned char player, unsigned max_route, bool random_route,
103
                                                          std::vector<Direction>* route, unsigned* length) const
104
{
105
    unsigned char owner = GetNode(dest).owner;
36✔
106
    if(owner != 0 && !GetPlayer(player).IsAlly(owner - 1))
36✔
107
        return boost::none;
14✔
108

109
    RTTR_Assert(GetNO(dest)->GetType() == NodalObjectType::Flag); // Goal should be the flag of a wh
22✔
110

111
    if(!PathConditionHuman(*this).IsNodeOk(dest))
44✔
112
        return boost::none;
×
113

114
    Direction first_dir{};
22✔
115
    if(GetFreePathFinder().FindPath(start, dest, random_route, max_route, route, length, &first_dir,
44✔
116
                                    PathConditionTrade(*this, player)))
44✔
117
        return first_dir;
18✔
118
    else
119
        return boost::none;
4✔
120
}
121

122
bool GameWorld::CheckTradeRoute(const MapPoint start, const std::vector<Direction>& route, unsigned pos,
190✔
123
                                unsigned char player, MapPoint* dest) const
124
{
125
    return GetFreePathFinder().CheckRoute(start, route, pos, PathConditionTrade(*this, player), dest);
190✔
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc