mirror of https://github.com/OpenTTD/OpenTTD.git
Merge 2ac8992786
into bf8de188ec
This commit is contained in:
commit
41fd78fb0f
|
@ -51,7 +51,6 @@ class WaterRegion
|
||||||
private:
|
private:
|
||||||
std::array<TWaterRegionTraversabilityBits, DIAGDIR_END> edge_traversability_bits{};
|
std::array<TWaterRegionTraversabilityBits, DIAGDIR_END> edge_traversability_bits{};
|
||||||
bool has_cross_region_aqueducts = false;
|
bool has_cross_region_aqueducts = false;
|
||||||
bool initialized = false;
|
|
||||||
TWaterRegionPatchLabel number_of_patches = 0; // 0 = no water, 1 = one single patch of water, etc...
|
TWaterRegionPatchLabel number_of_patches = 0; // 0 = no water, 1 = one single patch of water, etc...
|
||||||
const OrthogonalTileArea tile_area;
|
const OrthogonalTileArea tile_area;
|
||||||
std::unique_ptr<TWaterRegionPatchLabelArray> tile_patch_labels; ///< Tile patch labels, this may be nullptr in the following trivial cases: region is invalid, region is only land (0 patches), region is only water (1 patch)
|
std::unique_ptr<TWaterRegionPatchLabelArray> tile_patch_labels; ///< Tile patch labels, this may be nullptr in the following trivial cases: region is invalid, region is only land (0 patches), region is only water (1 patch)
|
||||||
|
@ -76,14 +75,6 @@ public:
|
||||||
OrthogonalTileIterator begin() const { return this->tile_area.begin(); }
|
OrthogonalTileIterator begin() const { return this->tile_area.begin(); }
|
||||||
OrthogonalTileIterator end() const { return this->tile_area.end(); }
|
OrthogonalTileIterator end() const { return this->tile_area.end(); }
|
||||||
|
|
||||||
bool IsInitialized() const { return this->initialized; }
|
|
||||||
|
|
||||||
void Invalidate()
|
|
||||||
{
|
|
||||||
if (!IsInitialized()) Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile));
|
|
||||||
this->initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a set of bits indicating whether an edge tile on a particular side is traversable or not. These
|
* Returns a set of bits indicating whether an edge tile on a particular side is traversable or not. These
|
||||||
* values can be used to determine whether a ship can enter/leave the region through a particular edge tile.
|
* values can be used to determine whether a ship can enter/leave the region through a particular edge tile.
|
||||||
|
@ -182,7 +173,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
this->number_of_patches = highest_assigned_label;
|
this->number_of_patches = highest_assigned_label;
|
||||||
this->initialized = true;
|
|
||||||
|
|
||||||
if (this->number_of_patches == 0 || (this->number_of_patches == 1 &&
|
if (this->number_of_patches == 0 || (this->number_of_patches == 1 &&
|
||||||
std::all_of(this->tile_patch_labels->begin(), this->tile_patch_labels->end(), [](TWaterRegionPatchLabel label) { return label == 1; }))) {
|
std::all_of(this->tile_patch_labels->begin(), this->tile_patch_labels->end(), [](TWaterRegionPatchLabel label) { return label == 1; }))) {
|
||||||
|
@ -191,14 +181,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the patch labels and other data, but only if the region is not yet initialized.
|
|
||||||
*/
|
|
||||||
inline void UpdateIfNotInitialized()
|
|
||||||
{
|
|
||||||
if (!this->initialized) ForceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintDebugInfo()
|
void PrintDebugInfo()
|
||||||
{
|
{
|
||||||
Debug(map, 9, "Water region {},{} labels and edge traversability = ...", GetWaterRegionX(tile_area.tile), GetWaterRegionY(tile_area.tile));
|
Debug(map, 9, "Water region {},{} labels and edge traversability = ...", GetWaterRegionX(tile_area.tile), GetWaterRegionY(tile_area.tile));
|
||||||
|
@ -228,6 +210,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<WaterRegion> _water_regions;
|
std::vector<WaterRegion> _water_regions;
|
||||||
|
std::vector<bool> _is_water_region_valid;
|
||||||
|
|
||||||
TileIndex GetTileIndexFromLocalCoordinate(int region_x, int region_y, int local_x, int local_y)
|
TileIndex GetTileIndexFromLocalCoordinate(int region_x, int region_y, int local_x, int local_y)
|
||||||
{
|
{
|
||||||
|
@ -250,16 +233,18 @@ TileIndex GetEdgeTileCoordinate(int region_x, int region_y, DiagDirection side,
|
||||||
|
|
||||||
WaterRegion &GetUpdatedWaterRegion(uint16_t region_x, uint16_t region_y)
|
WaterRegion &GetUpdatedWaterRegion(uint16_t region_x, uint16_t region_y)
|
||||||
{
|
{
|
||||||
WaterRegion &result = _water_regions[GetWaterRegionIndex(region_x, region_y)];
|
const int index = GetWaterRegionIndex(region_x, region_y);
|
||||||
result.UpdateIfNotInitialized();
|
auto &water_region = _water_regions[index];
|
||||||
return result;
|
if (!_is_water_region_valid[index]) {
|
||||||
|
water_region.ForceUpdate();
|
||||||
|
_is_water_region_valid[index] = true;
|
||||||
|
}
|
||||||
|
return water_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaterRegion &GetUpdatedWaterRegion(TileIndex tile)
|
WaterRegion &GetUpdatedWaterRegion(TileIndex tile)
|
||||||
{
|
{
|
||||||
WaterRegion &result = _water_regions[GetWaterRegionIndex(tile)];
|
return GetUpdatedWaterRegion(GetWaterRegionX(tile), GetWaterRegionY(tile));
|
||||||
result.UpdateIfNotInitialized();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -316,15 +301,21 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
|
||||||
void InvalidateWaterRegion(TileIndex tile)
|
void InvalidateWaterRegion(TileIndex tile)
|
||||||
{
|
{
|
||||||
if (!IsValidTile(tile)) return;
|
if (!IsValidTile(tile)) return;
|
||||||
|
|
||||||
|
auto invalidateRegion = [](TileIndex tile) {
|
||||||
const int water_region_index = GetWaterRegionIndex(tile);
|
const int water_region_index = GetWaterRegionIndex(tile);
|
||||||
_water_regions[water_region_index].Invalidate();
|
if (!_is_water_region_valid[water_region_index]) Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile));
|
||||||
|
_is_water_region_valid[water_region_index] = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
invalidateRegion(tile);
|
||||||
|
|
||||||
/* When updating the water region we look into the first tile of adjacent water regions to determine edge
|
/* When updating the water region we look into the first tile of adjacent water regions to determine edge
|
||||||
* traversability. This means that if we invalidate any region edge tiles we might also change the traversability
|
* traversability. This means that if we invalidate any region edge tiles we might also change the traversability
|
||||||
* of the adjacent region. This code ensures the adjacent regions also get invalidated in such a case. */
|
* of the adjacent region. This code ensures the adjacent regions also get invalidated in such a case. */
|
||||||
for (DiagDirection side = DIAGDIR_BEGIN; side < DIAGDIR_END; side++) {
|
for (DiagDirection side = DIAGDIR_BEGIN; side < DIAGDIR_END; side++) {
|
||||||
const int adjacent_region_index = GetWaterRegionIndex(TileAddByDiagDir(tile, side));
|
const TileIndex adjacent_tile = TileAddByDiagDir(tile, side);
|
||||||
if (adjacent_region_index != water_region_index) _water_regions[adjacent_region_index].Invalidate();
|
if (GetWaterRegionIndex(adjacent_tile) != GetWaterRegionIndex(tile)) invalidateRegion(adjacent_tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,8 +400,12 @@ void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_pat
|
||||||
*/
|
*/
|
||||||
void AllocateWaterRegions()
|
void AllocateWaterRegions()
|
||||||
{
|
{
|
||||||
|
const int number_of_regions = static_cast<size_t>(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY();
|
||||||
|
|
||||||
_water_regions.clear();
|
_water_regions.clear();
|
||||||
_water_regions.reserve(static_cast<size_t>(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY());
|
_water_regions.reserve(number_of_regions);
|
||||||
|
|
||||||
|
_is_water_region_valid.resize(number_of_regions, false);
|
||||||
|
|
||||||
Debug(map, 2, "Allocating {} x {} water regions", GetWaterRegionMapSizeX(), GetWaterRegionMapSizeY());
|
Debug(map, 2, "Allocating {} x {} water regions", GetWaterRegionMapSizeX(), GetWaterRegionMapSizeY());
|
||||||
|
|
||||||
|
@ -419,6 +414,8 @@ void AllocateWaterRegions()
|
||||||
_water_regions.emplace_back(region_x, region_y);
|
_water_regions.emplace_back(region_x, region_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(_is_water_region_valid.size() == _water_regions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintWaterRegionDebugInfo(TileIndex tile)
|
void PrintWaterRegionDebugInfo(TileIndex tile)
|
||||||
|
|
Loading…
Reference in New Issue