mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
3 Commits
9cc17230e8
...
60b6c6c7ee
Author | SHA1 | Date |
---|---|---|
|
60b6c6c7ee | |
|
35c89d57f8 | |
|
4b94457bf1 |
|
@ -1,3 +1,15 @@
|
||||||
|
14.0-beta2 (2023-02-04)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Change: [NewGRF] Improved support for redefining default cargo types (#11719)
|
||||||
|
Fix #11982: Crash when trying to place signals on things other than plain rails (#11977)
|
||||||
|
Fix #11975: Inconsistent behaviour when changing first AI company settings (#11976)
|
||||||
|
Fix #11972: Year cut off in graph windows (#11974)
|
||||||
|
Fix #11968: Crash when opening orders window of new vehicles (#11973)
|
||||||
|
Fix #11966: Monospace text in windows may not have been fully scrollable (#11981)
|
||||||
|
Fix #11802: Made determining water region edge traversability more robust (#11986)
|
||||||
|
Fix: Second colour vehicle-type default liveries were not being updated (#11971)
|
||||||
|
|
||||||
|
|
||||||
14.0-beta1 (2023-02-03)
|
14.0-beta1 (2023-02-03)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Feature: Order option to unbunch vehicles at depot (#11945)
|
Feature: Order option to unbunch vehicles at depot (#11945)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "rev.h"
|
#include "rev.h"
|
||||||
#include "timer/timer.h"
|
#include "timer/timer.h"
|
||||||
#include "timer/timer_window.h"
|
#include "timer/timer_window.h"
|
||||||
|
#include "pathfinder/water_regions.h"
|
||||||
|
|
||||||
#include "widgets/misc_widget.h"
|
#include "widgets/misc_widget.h"
|
||||||
|
|
||||||
|
@ -128,6 +129,8 @@ public:
|
||||||
Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6());
|
Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6());
|
||||||
Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7());
|
Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7());
|
||||||
Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8());
|
Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8());
|
||||||
|
|
||||||
|
PrintWaterRegionDebugInfo(tile);
|
||||||
#undef LANDINFOD_LEVEL
|
#undef LANDINFOD_LEVEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,11 @@ public:
|
||||||
|
|
||||||
bool IsInitialized() const { return this->initialized; }
|
bool IsInitialized() const { return this->initialized; }
|
||||||
|
|
||||||
void Invalidate() { this->initialized = false; }
|
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
|
||||||
|
@ -120,16 +124,7 @@ public:
|
||||||
this->has_cross_region_aqueducts = false;
|
this->has_cross_region_aqueducts = false;
|
||||||
|
|
||||||
this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
|
this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
|
||||||
|
this->edge_traversability_bits.fill(0);
|
||||||
for (const TileIndex tile : this->tile_area) {
|
|
||||||
if (IsAqueductTile(tile)) {
|
|
||||||
const TileIndex other_aqueduct_end = GetOtherBridgeEnd(tile);
|
|
||||||
if (!tile_area.Contains(other_aqueduct_end)) {
|
|
||||||
this->has_cross_region_aqueducts = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TWaterRegionPatchLabel current_label = 1;
|
TWaterRegionPatchLabel current_label = 1;
|
||||||
TWaterRegionPatchLabel highest_assigned_label = 0;
|
TWaterRegionPatchLabel highest_assigned_label = 0;
|
||||||
|
@ -158,7 +153,18 @@ public:
|
||||||
for (const Trackdir dir : SetTrackdirBitIterator(valid_dirs)) {
|
for (const Trackdir dir : SetTrackdirBitIterator(valid_dirs)) {
|
||||||
/* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */
|
/* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */
|
||||||
CFollowTrackWater ft;
|
CFollowTrackWater ft;
|
||||||
if (ft.Follow(tile, dir) && this->tile_area.Contains(ft.m_new_tile)) tiles_to_check.push_back(ft.m_new_tile);
|
if (ft.Follow(tile, dir)) {
|
||||||
|
if (this->tile_area.Contains(ft.m_new_tile)) {
|
||||||
|
tiles_to_check.push_back(ft.m_new_tile);
|
||||||
|
} else if (!ft.m_is_bridge) {
|
||||||
|
assert(DistanceManhattan(ft.m_new_tile, tile) == 1);
|
||||||
|
const auto side = DiagdirBetweenTiles(tile, ft.m_new_tile);
|
||||||
|
const int local_x_or_y = DiagDirToAxis(side) == AXIS_X ? TileY(tile) - TileY(this->tile_area.tile) : TileX(tile) - TileX(this->tile_area.tile);
|
||||||
|
SetBit(this->edge_traversability_bits[side], local_x_or_y);
|
||||||
|
} else {
|
||||||
|
this->has_cross_region_aqueducts = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,18 +173,6 @@ public:
|
||||||
|
|
||||||
this->number_of_patches = highest_assigned_label;
|
this->number_of_patches = highest_assigned_label;
|
||||||
this->initialized = true;
|
this->initialized = true;
|
||||||
|
|
||||||
/* Calculate the traversability (whether the tile can be entered / exited) for all edges. Note that
|
|
||||||
* we always follow the same X and Y scanning direction, this is important for comparisons later on! */
|
|
||||||
this->edge_traversability_bits.fill(0);
|
|
||||||
const int top_x = TileX(tile_area.tile);
|
|
||||||
const int top_y = TileY(tile_area.tile);
|
|
||||||
for (int i = 0; i < WATER_REGION_EDGE_LENGTH; ++i) {
|
|
||||||
if (GetWaterTracks(TileXY(top_x + i, top_y)) & TRACK_BIT_3WAY_NW) SetBit(this->edge_traversability_bits[DIAGDIR_NW], i); // NW edge
|
|
||||||
if (GetWaterTracks(TileXY(top_x + i, top_y + WATER_REGION_EDGE_LENGTH - 1)) & TRACK_BIT_3WAY_SE) SetBit(this->edge_traversability_bits[DIAGDIR_SE], i); // SE edge
|
|
||||||
if (GetWaterTracks(TileXY(top_x, top_y + i)) & TRACK_BIT_3WAY_NE) SetBit(this->edge_traversability_bits[DIAGDIR_NE], i); // NE edge
|
|
||||||
if (GetWaterTracks(TileXY(top_x + WATER_REGION_EDGE_LENGTH - 1, top_y + i)) & TRACK_BIT_3WAY_SW) SetBit(this->edge_traversability_bits[DIAGDIR_SW], i); // SW edge
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,6 +182,33 @@ public:
|
||||||
{
|
{
|
||||||
if (!this->initialized) ForceUpdate();
|
if (!this->initialized) ForceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintDebugInfo()
|
||||||
|
{
|
||||||
|
Debug(map, 9, "Water region {},{} labels and edge traversability = ...", GetWaterRegionX(tile_area.tile), GetWaterRegionY(tile_area.tile));
|
||||||
|
|
||||||
|
const size_t max_element_width = std::to_string(this->number_of_patches).size();
|
||||||
|
|
||||||
|
std::array<int, 16> traversability_NW{0};
|
||||||
|
for (auto bitIndex : SetBitIterator(edge_traversability_bits[DIAGDIR_NW])) *(traversability_NW.rbegin() + bitIndex) = 1;
|
||||||
|
Debug(map, 9, " {:{}}", fmt::join(traversability_NW, " "), max_element_width);
|
||||||
|
Debug(map, 9, " +{:->{}}+", "", WATER_REGION_EDGE_LENGTH * (max_element_width + 1) + 1);
|
||||||
|
|
||||||
|
for (int y = 0; y < WATER_REGION_EDGE_LENGTH; ++y) {
|
||||||
|
std::string line{};
|
||||||
|
for (int x = 0; x < WATER_REGION_EDGE_LENGTH; ++x) {
|
||||||
|
const auto label = this->tile_patch_labels[x + y * WATER_REGION_EDGE_LENGTH];
|
||||||
|
const std::string label_str = label == INVALID_WATER_REGION_PATCH ? "." : std::to_string(label);
|
||||||
|
line = fmt::format("{:{}}", label_str, max_element_width) + " " + line;
|
||||||
|
}
|
||||||
|
Debug(map, 9, "{} | {}| {}", GB(this->edge_traversability_bits[DIAGDIR_SW], y, 1), line, GB(this->edge_traversability_bits[DIAGDIR_NE], y, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(map, 9, " +{:->{}}+", "", WATER_REGION_EDGE_LENGTH * (max_element_width + 1) + 1);
|
||||||
|
std::array<int, 16> traversability_SE{0};
|
||||||
|
for (auto bitIndex : SetBitIterator(edge_traversability_bits[DIAGDIR_SE])) *(traversability_SE.rbegin() + bitIndex) = 1;
|
||||||
|
Debug(map, 9, " {:{}}", fmt::join(traversability_SE, " "), max_element_width);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<WaterRegion> _water_regions;
|
std::vector<WaterRegion> _water_regions;
|
||||||
|
@ -278,10 +299,17 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
|
||||||
*/
|
*/
|
||||||
void InvalidateWaterRegion(TileIndex tile)
|
void InvalidateWaterRegion(TileIndex tile)
|
||||||
{
|
{
|
||||||
const int index = GetWaterRegionIndex(tile);
|
if (!IsValidTile(tile)) return;
|
||||||
_water_regions[index].Invalidate();
|
const int water_region_index = GetWaterRegionIndex(tile);
|
||||||
|
_water_regions[water_region_index].Invalidate();
|
||||||
|
|
||||||
Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile));
|
/* 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
|
||||||
|
* 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++) {
|
||||||
|
const int adjacent_region_index = GetWaterRegionIndex(TileAddByDiagDir(tile, side));
|
||||||
|
if (adjacent_region_index != water_region_index) _water_regions[adjacent_region_index].Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -371,3 +399,8 @@ void AllocateWaterRegions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintWaterRegionDebugInfo(TileIndex tile)
|
||||||
|
{
|
||||||
|
GetUpdatedWaterRegion(tile).PrintDebugInfo();
|
||||||
|
}
|
||||||
|
|
|
@ -64,4 +64,6 @@ void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_pat
|
||||||
|
|
||||||
void AllocateWaterRegions();
|
void AllocateWaterRegions();
|
||||||
|
|
||||||
|
void PrintWaterRegionDebugInfo(TileIndex tile);
|
||||||
|
|
||||||
#endif /* WATER_REGIONS_H */
|
#endif /* WATER_REGIONS_H */
|
||||||
|
|
Loading…
Reference in New Issue