Skip to content

Commit

Permalink
Feature: Region-based pathfinder for ships
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuhnovic committed Jan 2, 2024
1 parent 502a52e commit d3124c5
Show file tree
Hide file tree
Showing 23 changed files with 1,269 additions and 146 deletions.
4 changes: 3 additions & 1 deletion src/depot_gui.cpp
Expand Up @@ -902,7 +902,9 @@ struct DepotWindow : Window {
{
if (_ctrl_pressed) {
/* Share-clone, do not open new viewport, and keep tool active */
Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, true);
//for (int i = 0; i < 200; ++i) { // TODO KB for performance testing, remove again
Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, true);
//}

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.
} else {
/* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */
if (Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, false)) {
Expand Down
3 changes: 3 additions & 0 deletions src/genworld.cpp
Expand Up @@ -35,6 +35,7 @@
#include "string_func.h"
#include "thread.h"
#include "tgp.h"
#include "pathfinder/water_regions.h"

#include "safeguards.h"

Expand Down Expand Up @@ -174,6 +175,8 @@ static void _GenerateWorld()
}
}

InitializeWaterRegions();

BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);

ResetObjectToPlace();
Expand Down
2 changes: 2 additions & 0 deletions src/pathfinder/CMakeLists.txt
Expand Up @@ -5,4 +5,6 @@ add_files(
follow_track.hpp
pathfinder_func.h
pathfinder_type.h
water_regions.h
water_regions.cpp
)
404 changes: 404 additions & 0 deletions src/pathfinder/water_regions.cpp

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions src/pathfinder/water_regions.h
@@ -0,0 +1,77 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file water_regions.h Handles dividing the water in the map into regions to assist pathfinding. */

#ifndef WATER_REGIONS_H
#define WATER_REGIONS_H

#include "tile_type.h"
#include "map_func.h"

using TWaterRegionPatchLabel = uint8_t;
using TWaterRegionIndex = uint;

constexpr int WATER_REGION_EDGE_LENGTH = 16;
constexpr int WATER_REGION_NUMBER_OF_TILES = WATER_REGION_EDGE_LENGTH * WATER_REGION_EDGE_LENGTH;

/**
* Describes a single interconnected patch of water within a particular water region.
*/
struct WaterRegionPatchDesc
{
int x; ///< Water region X coordinate
int y; ///< Water region Y coordinate
TWaterRegionPatchLabel label; // Unique label identifying the patch within the region

bool operator==(const WaterRegionPatchDesc &other) const { return x == other.x && y == other.y && label == other.label; }
bool operator!=(const WaterRegionPatchDesc &other) const { return !(*this == other); }
};


/**
* Describes a single square water region.
*/
struct WaterRegionDesc
{
int x; ///< Water region X coordinate.
int y; ///< Water region Y coordinate.

WaterRegionDesc(const int x, const int y) : x(x), y(y) {}
WaterRegionDesc(const WaterRegionPatchDesc &water_region_patch) : x(water_region_patch.x), y(water_region_patch.y) {}

bool operator==(const WaterRegionDesc &other) const { return x == other.x && y == other.y; }
bool operator!=(const WaterRegionDesc &other) const { return !(*this == other); }
};

TWaterRegionIndex GetWaterRegionIndex(const WaterRegionDesc &water_region);

TileIndex GetWaterRegionCenterTile(const WaterRegionDesc &water_region);

WaterRegionDesc GetWaterRegionInfo(TileIndex tile);
WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile);

void InvalidateWaterRegion(TileIndex tile);

using TVisitWaterRegionPatchCallBack = std::function<void(const WaterRegionPatchDesc &)>;
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback);

void InitializeWaterRegions();

/* TODO KB remove these */
void DEBUG_MarkRegion(int x, int y, int label, int color, bool override = false); // 0 = normal, 1 = red, 2 = blue, 3 = black, 4 = transparent
void DEBUG_MarkRegion(TWaterRegionIndex region_index, int color, bool override = false); // 0 = normal, 1 = red, 2 = blue, 3 = black, 4 = transparent

struct WaterRegionSaveLoadInfo
{
bool initialized;
};

std::vector<WaterRegionSaveLoadInfo> GetWaterRegionSaveLoadInfo();
void LoadWaterRegions(const std::vector<WaterRegionSaveLoadInfo> &save_load_info);

#endif /* WATER_REGIONS_H */
2 changes: 2 additions & 0 deletions src/pathfinder/yapf/CMakeLists.txt
Expand Up @@ -16,5 +16,7 @@ add_files(
yapf_rail.cpp
yapf_road.cpp
yapf_ship.cpp
yapf_ship_regions.h
yapf_ship_regions.cpp
yapf_type.hpp
)
19 changes: 16 additions & 3 deletions src/pathfinder/yapf/yapf_base.hpp
Expand Up @@ -12,6 +12,7 @@

#include "../../debug.h"
#include "../../settings_type.h"
#include "viewport_func.h"

/**
* CYapfBaseT - A-star type path finder base class.
Expand Down Expand Up @@ -43,6 +44,9 @@
* declaration. There are some examples. For another example look at
* test_yapf.h (part or unittest project).
*/

#define ENABLE_YAPF_DEBUG_DRAWING 1 // TODO KB Remove

template <class Types>
class CYapfBaseT {
public:
Expand Down Expand Up @@ -79,11 +83,11 @@ class CYapfBaseT {
, m_stats_cost_calcs(0)
, m_stats_cache_hits(0)
, m_num_steps(0)
{
}
{}

/** default destructor */
~CYapfBaseT() {}
~CYapfBaseT()
{}

protected:
/** to access inherited path finder */
Expand Down Expand Up @@ -131,6 +135,9 @@ class CYapfBaseT {
if (m_max_search_nodes == 0 || m_nodes.ClosedCount() < m_max_search_nodes) {
m_nodes.PopOpenNode(n->GetKey());
m_nodes.InsertClosedNode(*n);
#ifdef ENABLE_YAPF_DEBUG_DRAWING
DEBUG_addDrawInstruction(n->GetTile(), TrackdirToTrack(n->GetTrackdir()), 3, true);// 0 = normal, 1 = red, 2 = blue, 3 = black, 4 = transparent
#endif
} else {
bDestFound = false;
break;
Expand Down Expand Up @@ -176,6 +183,9 @@ class CYapfBaseT {
/** Add new node (created by CreateNewNode and filled with data) into open list */
inline void AddStartupNode(Node &n)
{
#ifdef ENABLE_YAPF_DEBUG_DRAWING
DEBUG_addDrawInstruction(n.GetTile(), TrackdirToTrack(n.GetTrackdir()), 3);// 0 = normal, 1 = red, 2 = blue, 3 = black, 4 = transparent
#endif
Yapf().PfNodeCacheFetch(n);
/* insert the new node only if it is not there */
if (m_nodes.FindOpenNode(n.m_key) == nullptr) {
Expand Down Expand Up @@ -293,6 +303,9 @@ class CYapfBaseT {
/* the new node is really new
* add it to the open list */
m_nodes.InsertOpenNode(n);
#ifdef ENABLE_YAPF_DEBUG_DRAWING
DEBUG_addDrawInstruction(n.GetTile(), TrackdirToTrack(n.GetTrackdir()), 1);// 0 = normal, 1 = red, 2 = blue, 3 = black, 4 = transparent
#endif
if (set_intermediate) m_pBestIntermediateNode = &n;
}

Expand Down

0 comments on commit d3124c5

Please sign in to comment.