From 50fe6727cb7e23ff31130199515793ff6cba6156 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:12:26 -0500 Subject: [PATCH 01/18] #5031: Handle top ramps when pathfinding to depot --- plugins/pathable.cpp | 81 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 579ffb17f1..0228065eff 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -240,6 +240,31 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df return false; } +static bool is_wagon_traversible_by_ramp(FloodCtx & ctx, const df::coord & pos) { + if ((is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos)) || // Top + + (is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos)) || // Middle + + (is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos)) || // Bottom + + (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos)) || // Left + + (is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) { // Right + return true; + } + return false; +} + static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { if (ctx.seen.contains(pos)) return; @@ -252,15 +277,53 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { return; } - if (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos)) - { + auto tt = Maps::getTileType(pos); + if (!tt) + return; + + auto shape = tileShape(*tt); + +#if 0 + if (shape == df::tiletype_shape::RAMP_TOP) { + std::cerr << "check_wagon_tile start" << std::endl; + bool r = is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(0, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(0, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + std::cerr << "check_wagon_tile end" << std::endl; + } +#endif + + + if ((shape != df::tiletype_shape::RAMP_TOP && + (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) || + (shape == df::tiletype_shape::RAMP_TOP && is_wagon_traversible_by_ramp(ctx, pos))) { ctx.wagon_path.emplace(pos); ctx.search_edge.emplace(pos); } From 7e6ec6fe852dfffdd5510a5d3bd9e54a48991b5f Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:52:41 -0500 Subject: [PATCH 02/18] #5031: Assign RAMP_TOP a walkability group from an adjacent tile --- library/modules/Maps.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- plugins/pathable.cpp | 2 +- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index c207360ac4..ae309c29c1 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -757,9 +757,45 @@ bool Maps::ReadGeology(vector > *layer_mats, vector return true; } -uint16_t Maps::getWalkableGroup(df::coord pos) { +uint16_t getNeighborWalkableGroup(df::map_block * block, df::coord pos) { + auto neighborGroup = [block, pos](int dx, int dy) { + return index_tile(block->walkable, pos + df::coord(dx, dy, 0)); + }; + + constexpr std::array, 8> directions = {{ + {-1, -1}, {0, -1}, {1, -1}, + {-1, 0}, {1, 0}, + {-1, 1}, {0, 1}, {1, 1} + }}; + + for (const auto& [dx, dy] : directions) { + uint16_t g = neighborGroup(dx, dy); + if (g) return g; + } + return 0; +} + +uint16_t Maps::getWalkableGroup(df::coord pos) +{ auto block = getTileBlock(pos); - return block ? index_tile(block->walkable, pos) : 0; + if (!block) return 0; + + /* + * RAMP_TOP tiles do not have a walkability group assigned to them directly. + * To determine walkability, we assign the group of an adjacent tile, + * with the constraint that the assigned group matches the walkability group + * of the same tile one z-level below. + */ + auto tt = getTileType(pos); + if (tt && tileShape(*tt) == df::tiletype_shape::RAMP_TOP) { + auto below_group = getWalkableGroup(pos + df::coord(0, 0, -1)); + if (below_group != 0) { + auto neigh_group = getNeighborWalkableGroup(block, pos); + return below_group == neigh_group ? neigh_group : 0; + } + } + + return index_tile(block->walkable, pos); } bool Maps::canWalkBetween(df::coord pos1, df::coord pos2) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 0228065eff..e3882c381d 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -298,7 +298,7 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); + r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); From ec83a702ffe8c545882b18c8cecc5efdeac8bc87 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:55:22 -0500 Subject: [PATCH 03/18] #5031: Remove debug prints --- plugins/pathable.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index e3882c381d..8535ce2ab9 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -282,38 +282,6 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { return; auto shape = tileShape(*tt); - -#if 0 - if (shape == df::tiletype_shape::RAMP_TOP) { - std::cerr << "check_wagon_tile start" << std::endl; - bool r = is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(0, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(0, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - std::cerr << "check_wagon_tile end" << std::endl; - } -#endif - - if ((shape != df::tiletype_shape::RAMP_TOP && (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && From 2b768683acba766e86a4cbd049c02a28c39d11c6 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:04:59 -0500 Subject: [PATCH 04/18] #5031: Fix MSVC build. Missing headers? --- library/modules/Maps.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index ae309c29c1..9206ae5a8f 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -63,6 +63,8 @@ distribution. #include "df/world_underground_region.h" #include "df/z_level_flags.h" +#include +#include #include #include #include From 3c7a3b22bfaa0e3aeff39b777f01e89d7a9d0b2c Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 30 Nov 2024 13:48:41 -0500 Subject: [PATCH 05/18] #5031: make wagon_flood() check it reaches an edge tile for correctly reporting wagon accessibility --- plugins/pathable.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 8535ce2ab9..28969dc1ad 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -214,6 +214,7 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df return false; auto shape = tileShape(*tt); + if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_UPDOWN) return false; @@ -272,7 +273,7 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { ctx.seen.emplace(pos); if (ctx.entry_tiles.contains(pos)) { - ctx.wagon_path.emplace(pos); + ctx.wagon_path.emplace(pos); // Is this needed? ctx.search_edge.emplace(pos); return; } @@ -323,7 +324,8 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat TRACE(log,out).print("checking tile: (%d, %d, %d); pathability group: %d\n", pos.x, pos.y, pos.z, Maps::getWalkableGroup(pos)); - if (entry_tiles.contains(pos)) { + // Ensure our wagon flood end points lands on an edge tile. + if ((pos.x == 0 || pos.y == 0) && entry_tiles.contains(pos)) { found = true; if (!wagon_path) break; From 8ea4f6afac3e8e6788eba1060ca4d1577835ad50 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:18:32 -0500 Subject: [PATCH 06/18] #5031: Make wagon pathability tests more robust --- plugins/pathable.cpp | 84 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 28969dc1ad..ff8e2938b2 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -2,6 +2,11 @@ #include "PluginManager.h" #include "TileTypes.h" +#include "df/building_type.h" +#include "df/building_hatchst.h" +#include "df/building_bars_floorst.h" +#include "df/building_grate_floorst.h" +#include "df/tile_building_occ.h" #include "modules/Buildings.h" #include "modules/Gui.h" #include "modules/Maps.h" @@ -202,25 +207,74 @@ struct FloodCtx { : wgroup(wgroup), wagon_path(wagon_path), entry_tiles(entry_tiles) {} }; -static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df::coord & prev_pos) { - if (auto bld = Buildings::findAtTile(pos)) { - auto btype = bld->getType(); - if (btype == df::building_type::Trap || btype == df::building_type::Door) +static bool is_wagon_dynamic_traversible(df::tiletype_shape shape, const df::coord & pos) { + auto bld = Buildings::findAtTile(pos); + if (!bld) return false; + + auto btype = bld->getType(); + // open hatch should be inaccessible regardless of the tile it sits on + if (btype == df::building_type::Hatch) { + if (shape == df::tiletype_shape::RAMP_TOP) return false; + + auto& hatch = *static_cast(bld); + if (hatch.door_flags.bits.closed) + return true; + // open floor grate/bar should be inaccessible regardless of the tile it sits on + } else if (btype == df::building_type::GrateFloor) { + auto& b = *static_cast(bld); + if (b.gate_flags.bits.closed) + return true; + } else if (btype == df::building_type::BarsFloor) { + auto& b = *static_cast(bld); + if (b.gate_flags.bits.closed) + return true; } + // Doors, traps..etc + return false; +} +static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df::coord & prev_pos) { auto tt = Maps::getTileType(pos); if (!tt) return false; auto shape = tileShape(*tt); - if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_UPDOWN) - return false; + auto& occ = *Maps::getTileOccupancy(pos); + switch (occ.bits.building) { + case tile_building_occ::Obstacle: // Statue + //fallthrough + case tile_building_occ::Well: + //fallthrough + case tile_building_occ::Impassable: + return false; + + case tile_building_occ::Dynamic: // doors(block), levers (block), traps (block), hatches (OK, but block on down ramp), closed floor grates (OK), closed floor bars (OK) + if (is_wagon_dynamic_traversible(shape, pos) == false) + return false; + break; + case tile_building_occ::None: // Not occupied by a building + // TODO smoothed boulders are traversable + if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_DOWN || + shape == df::tiletype_shape::STAIR_UPDOWN || shape == df::tiletype_shape::BOULDER || + shape == df::tiletype_shape::EMPTY || shape == df::tiletype_shape::NONE) + return false; + break; + case tile_building_occ::Planned: + //fallthrough + case tile_building_occ::Passable: // bed, support, rollers, armor/weapon stand, bed, cage, open wall grate/vertical bars + //fallthrough + case tile_building_occ::Floored: // depot, lowered bridge, forbidden hatch + default: + break; + } if (ctx.wgroup == Maps::getWalkableGroup(pos)) return true; + // RAMP_TOP is assigned a walkability group if that commit is accepted + // so this test, I think, would be useless. if (shape == df::tiletype_shape::RAMP_TOP ) { df::coord pos_below = pos + df::coord(0, 0, -1); if (Maps::getWalkableGroup(pos_below)) { @@ -296,6 +350,22 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { ctx.wagon_path.emplace(pos); ctx.search_edge.emplace(pos); } + +#if 0 + // Use this if we don't mind red Xs on down ramps + if ((is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) { + ctx.wagon_path.emplace(pos); + ctx.search_edge.emplace(pos); + } +#endif + } // returns true if a continuous 3-wide path can be found to an entry tile @@ -325,6 +395,8 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat Maps::getWalkableGroup(pos)); // Ensure our wagon flood end points lands on an edge tile. + // When there is no path to the depot entry_tiles will not + // contain any edge tiles. if ((pos.x == 0 || pos.y == 0) && entry_tiles.contains(pos)) { found = true; if (!wagon_path) From a0a37f39f54fa074f69b1d0ec80ba4043030d1b6 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:51:33 -0500 Subject: [PATCH 07/18] Correctly handle wagon accessible tiles for passable buildings --- plugins/pathable.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index ec8af8bc76..cf7fde2b5d 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -235,6 +235,15 @@ static bool is_wagon_dynamic_traversible(df::tiletype_shape shape, const df::coo return false; } +static bool is_wagon_tile_traversible(df::tiletype_shape shape) { + // TODO: smoothed boulders are traversible + if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_DOWN || + shape == df::tiletype_shape::STAIR_UPDOWN || shape == df::tiletype_shape::BOULDER || + shape == df::tiletype_shape::EMPTY || shape == df::tiletype_shape::NONE) + return false; + return true; +} + static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df::coord & prev_pos) { auto tt = Maps::getTileType(pos); if (!tt) @@ -245,29 +254,34 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df auto& occ = *Maps::getTileOccupancy(pos); switch (occ.bits.building) { case tile_building_occ::Obstacle: // Statue - //fallthrough + //FALLTHROUGH case tile_building_occ::Well: - //fallthrough - case tile_building_occ::Impassable: + //FALLTHROUGH + case tile_building_occ::Impassable: // Raised bridge return false; - case tile_building_occ::Dynamic: // doors(block), levers (block), traps (block), hatches (OK, but block on down ramp), closed floor grates (OK), closed floor bars (OK) + case tile_building_occ::Dynamic: + // doors(block), levers (block), traps (block), hatches (OK, but block on down ramp) + // closed floor grates (OK), closed floor bars (OK) if (is_wagon_dynamic_traversible(shape, pos) == false) return false; break; + case tile_building_occ::None: // Not occupied by a building - // TODO smoothed boulders are traversable - if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_DOWN || - shape == df::tiletype_shape::STAIR_UPDOWN || shape == df::tiletype_shape::BOULDER || - shape == df::tiletype_shape::EMPTY || shape == df::tiletype_shape::NONE) + //FALLTHROUGH + case tile_building_occ::Planned: + //FALLTHROUGH + case tile_building_occ::Passable: + // bed, support, rollers, armor/weapon stand, cage (not trap) + // open wall grate/vertical bars, retracted bridge, open floodgate + if (is_wagon_tile_traversible(shape) == false) return false; break; - case tile_building_occ::Planned: - //fallthrough - case tile_building_occ::Passable: // bed, support, rollers, armor/weapon stand, bed, cage, open wall grate/vertical bars - //fallthrough - case tile_building_occ::Floored: // depot, lowered bridge, forbidden hatch + case tile_building_occ::Floored: + // depot, lowered bridge, retracable bridge, forbidden hatch + break; default: + //NOTREACHED break; } From 2a1a7345793c5e56929435071d52e9ab6bd1300c Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:00:18 -0500 Subject: [PATCH 08/18] #5031: handle tracks, murky pool and river tiles --- plugins/pathable.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index cf7fde2b5d..4dba417a05 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -235,12 +235,28 @@ static bool is_wagon_dynamic_traversible(df::tiletype_shape shape, const df::coo return false; } -static bool is_wagon_tile_traversible(df::tiletype_shape shape) { - // TODO: smoothed boulders are traversible - if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_DOWN || +// NOTE: When i.e. tracks, stairs have a bridge over them, the tile will have +// an occupancy of floored. +static bool is_wagon_tile_traversible(df::tiletype& tt) { + auto shape = tileShape(tt); + auto special = tileSpecial(tt); + auto material = tileMaterial(tt); + + // Allow murky pool ramps + if (shape == df::tiletype_shape::RAMP_TOP) + return true; + // NOTE: smoothing a boulder turns it into a smoothed floor + else if (shape == df::tiletype_shape::STAIR_UP || shape == df::tiletype_shape::STAIR_DOWN || shape == df::tiletype_shape::STAIR_UPDOWN || shape == df::tiletype_shape::BOULDER || shape == df::tiletype_shape::EMPTY || shape == df::tiletype_shape::NONE) return false; + else if (special == df::tiletype_special::TRACK) + return false; + // Fires seem to have their own path group, and group for lava is 0 + // According to wiki, the wagon won't path thru pool and river tiles, but ramps are ok + else if (material == df::tiletype_material::POOL || material == df::tiletype_material::RIVER) + return false; + return true; } @@ -250,14 +266,13 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df return false; auto shape = tileShape(*tt); - auto& occ = *Maps::getTileOccupancy(pos); switch (occ.bits.building) { - case tile_building_occ::Obstacle: // Statue + case tile_building_occ::Obstacle: // Statues, windmills (middle tile) //FALLTHROUGH case tile_building_occ::Well: //FALLTHROUGH - case tile_building_occ::Impassable: // Raised bridge + case tile_building_occ::Impassable: // Raised bridges return false; case tile_building_occ::Dynamic: @@ -272,13 +287,15 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df case tile_building_occ::Planned: //FALLTHROUGH case tile_building_occ::Passable: - // bed, support, rollers, armor/weapon stand, cage (not trap) - // open wall grate/vertical bars, retracted bridge, open floodgate - if (is_wagon_tile_traversible(shape) == false) + // Any tile with no building or a passable building including + // beds, supports, rollers, armor/weapon stands, cages (not traps), + // open wall grate/vertical bars, retracted bridges, open floodgates, + // workshops (tiles with open space are handled by the tile check) + if (is_wagon_tile_traversible(*tt) == false) return false; break; case tile_building_occ::Floored: - // depot, lowered bridge, retracable bridge, forbidden hatch + // depot, lowered bridges or retractable bridges, forbidden hatches break; default: //NOTREACHED From 7c384c9ef9e573e1b40ef219d175c594b1c575e1 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:54:38 -0500 Subject: [PATCH 09/18] Revert "#5031: Fix MSVC build. Missing headers?" This reverts commit 2b768683acba766e86a4cbd049c02a28c39d11c6. --- library/modules/Maps.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 9206ae5a8f..ae309c29c1 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -63,8 +63,6 @@ distribution. #include "df/world_underground_region.h" #include "df/z_level_flags.h" -#include -#include #include #include #include From 464ef96a1763abc32b075e8981a552c54f40acfd Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:56:41 -0500 Subject: [PATCH 10/18] Revert "#5031: Remove debug prints" This reverts commit ec83a702ffe8c545882b18c8cecc5efdeac8bc87. --- plugins/pathable.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 4dba417a05..040a5c4773 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -369,6 +369,38 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { return; auto shape = tileShape(*tt); + +#if 0 + if (shape == df::tiletype_shape::RAMP_TOP) { + std::cerr << "check_wagon_tile start" << std::endl; + bool r = is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(0, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(0, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + + r = is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos); + std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; + std::cerr << "check_wagon_tile end" << std::endl; + } +#endif + + if ((shape != df::tiletype_shape::RAMP_TOP && (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && From 47eb2ed6eaa9d68b6bb760457b1645320e2a9825 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:57:08 -0500 Subject: [PATCH 11/18] Revert "#5031: Assign RAMP_TOP a walkability group from an adjacent tile" This reverts commit 7e6ec6fe852dfffdd5510a5d3bd9e54a48991b5f. --- library/modules/Maps.cpp | 40 ++-------------------------------------- plugins/pathable.cpp | 2 +- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index ae309c29c1..c207360ac4 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -757,45 +757,9 @@ bool Maps::ReadGeology(vector > *layer_mats, vector return true; } -uint16_t getNeighborWalkableGroup(df::map_block * block, df::coord pos) { - auto neighborGroup = [block, pos](int dx, int dy) { - return index_tile(block->walkable, pos + df::coord(dx, dy, 0)); - }; - - constexpr std::array, 8> directions = {{ - {-1, -1}, {0, -1}, {1, -1}, - {-1, 0}, {1, 0}, - {-1, 1}, {0, 1}, {1, 1} - }}; - - for (const auto& [dx, dy] : directions) { - uint16_t g = neighborGroup(dx, dy); - if (g) return g; - } - return 0; -} - -uint16_t Maps::getWalkableGroup(df::coord pos) -{ +uint16_t Maps::getWalkableGroup(df::coord pos) { auto block = getTileBlock(pos); - if (!block) return 0; - - /* - * RAMP_TOP tiles do not have a walkability group assigned to them directly. - * To determine walkability, we assign the group of an adjacent tile, - * with the constraint that the assigned group matches the walkability group - * of the same tile one z-level below. - */ - auto tt = getTileType(pos); - if (tt && tileShape(*tt) == df::tiletype_shape::RAMP_TOP) { - auto below_group = getWalkableGroup(pos + df::coord(0, 0, -1)); - if (below_group != 0) { - auto neigh_group = getNeighborWalkableGroup(block, pos); - return below_group == neigh_group ? neigh_group : 0; - } - } - - return index_tile(block->walkable, pos); + return block ? index_tile(block->walkable, pos) : 0; } bool Maps::canWalkBetween(df::coord pos1, df::coord pos2) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 040a5c4773..a8e34b1875 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -385,7 +385,7 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); + r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); From 3acd1eb6c81054a491aed0489151b445d4960a74 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:57:30 -0500 Subject: [PATCH 12/18] Revert "#5031: Handle top ramps when pathfinding to depot" This reverts commit 50fe6727cb7e23ff31130199515793ff6cba6156. --- plugins/pathable.cpp | 81 +++++--------------------------------------- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index a8e34b1875..7f25fdfdec 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -327,31 +327,6 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df return false; } -static bool is_wagon_traversible_by_ramp(FloodCtx & ctx, const df::coord & pos) { - if ((is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos)) || // Top - - (is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos)) || // Middle - - (is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos)) || // Bottom - - (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos)) || // Left - - (is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) { // Right - return true; - } - return false; -} - static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { if (ctx.seen.contains(pos)) return; @@ -364,53 +339,15 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { return; } - auto tt = Maps::getTileType(pos); - if (!tt) - return; - - auto shape = tileShape(*tt); - -#if 0 - if (shape == df::tiletype_shape::RAMP_TOP) { - std::cerr << "check_wagon_tile start" << std::endl; - bool r = is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(0, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, -1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 0, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( -1, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(-1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(0, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - - r = is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos); - std::cerr << r << ", " + coord_to_str(pos+df::coord(1, 1, 0)) + ", pos=" + coord_to_str(pos) << std::endl; - std::cerr << "check_wagon_tile end" << std::endl; - } -#endif - - - if ((shape != df::tiletype_shape::RAMP_TOP && - (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) || - (shape == df::tiletype_shape::RAMP_TOP && is_wagon_traversible_by_ramp(ctx, pos))) { + if (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && + is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos)) + { ctx.wagon_path.emplace(pos); ctx.search_edge.emplace(pos); } From 0063cd7433193171fdaa623690e40108eb888d41 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 15:01:33 -0500 Subject: [PATCH 13/18] remove invalidated RAMP_TOP comment remove invalidated RAMP_TOP code --- plugins/pathable.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 7f25fdfdec..8325b57b2a 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -305,8 +305,6 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df if (ctx.wgroup == Maps::getWalkableGroup(pos)) return true; - // RAMP_TOP is assigned a walkability group if that commit is accepted - // so this test, I think, would be useless. if (shape == df::tiletype_shape::RAMP_TOP ) { df::coord pos_below = pos + df::coord(0, 0, -1); if (Maps::getWalkableGroup(pos_below)) { @@ -351,22 +349,6 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { ctx.wagon_path.emplace(pos); ctx.search_edge.emplace(pos); } - -#if 0 - // Use this if we don't mind red Xs on down ramps - if ((is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 0, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord(-1, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 0, 1, 0), pos) && - is_wagon_traversible(ctx, pos+df::coord( 1, 1, 0), pos))) { - ctx.wagon_path.emplace(pos); - ctx.search_edge.emplace(pos); - } -#endif - } // returns true if a continuous 3-wide path can be found to an entry tile From 67497ed006737f231e804d32cdbefba41fcd1953 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 17:44:20 -0500 Subject: [PATCH 14/18] #5031: update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index f4249c5572..a8c92419d3 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -78,6 +78,7 @@ Template for new versions: - `timestream`: improve FPS by a further 10% - `fix/occupancy`: additionally handle the case where tile building occupancy needs to be set instead of cleared - `orders`: ``orders sort`` now moves orders that are tied to a specific workshop to the top of the list in the overall manager orders screen +- `gui/pathable`: make wagon path to depot representation more robust ## Documentation - Dreamfort: add link to Dreamfort tutorial youtube series: https://www.youtube.com/playlist?list=PLzXx9JcB9oXxmrtkO1y8ZXzBCFEZrKxve From 10dd5d04b75ff82c6c35a8335d000b10ce19c8f0 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sat, 7 Dec 2024 22:06:21 -0500 Subject: [PATCH 15/18] #5031: check the center too. maybe fix errant passable trees/boulders. --- plugins/pathable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 8325b57b2a..53df5c0a02 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -337,7 +337,8 @@ static void check_wagon_tile(FloodCtx & ctx, const df::coord & pos) { return; } - if (is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && + if (is_wagon_traversible(ctx, pos, pos) && + is_wagon_traversible(ctx, pos+df::coord(-1, -1, 0), pos) && is_wagon_traversible(ctx, pos+df::coord( 0, -1, 0), pos) && is_wagon_traversible(ctx, pos+df::coord( 1, -1, 0), pos) && is_wagon_traversible(ctx, pos+df::coord(-1, 0, 0), pos) && From e9262102767e758898e9a6c345478296ad4f17e3 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 8 Dec 2024 21:23:57 -0500 Subject: [PATCH 16/18] #5031: check if path exists for bottom and right edge tiles too, plus resolve some other issues --- plugins/pathable.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 53df5c0a02..0c8b45d205 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -237,7 +237,7 @@ static bool is_wagon_dynamic_traversible(df::tiletype_shape shape, const df::coo // NOTE: When i.e. tracks, stairs have a bridge over them, the tile will have // an occupancy of floored. -static bool is_wagon_tile_traversible(df::tiletype& tt) { +static bool is_wagon_tile_traversible(df::tiletype tt) { auto shape = tileShape(tt); auto special = tileSpecial(tt); auto material = tileMaterial(tt); @@ -266,7 +266,10 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df return false; auto shape = tileShape(*tt); - auto& occ = *Maps::getTileOccupancy(pos); + auto occp = Maps::getTileOccupancy(pos); + if (!occp) + return false; + auto & occ = *occp; switch (occ.bits.building) { case tile_building_occ::Obstacle: // Statues, windmills (middle tile) //FALLTHROUGH @@ -371,6 +374,12 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat ctx.wagon_path.emplace(depot_pos); ctx.seen.emplace(depot_pos); ctx.search_edge.emplace(depot_pos); + + auto & edge = plotinfo->map_edge; + size_t num_edge_tiles = edge.surface_x.size(); + int max_edge_x = edge.surface_x[num_edge_tiles - 1]; + int max_edge_y = edge.surface_y[num_edge_tiles - 1]; + while (!ctx.search_edge.empty()) { df::coord pos = ctx.search_edge.top(); ctx.search_edge.pop(); @@ -379,9 +388,9 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat Maps::getWalkableGroup(pos)); // Ensure our wagon flood end points lands on an edge tile. - // When there is no path to the depot entry_tiles will not + // When there is no path to the depot search_edge will not // contain any edge tiles. - if ((pos.x == 0 || pos.y == 0) && entry_tiles.contains(pos)) { + if ((pos.x == 0 || pos.y == 0 || pos.x == max_edge_x || pos.y == max_edge_y) && entry_tiles.contains(pos)) { found = true; if (!wagon_path) break; From ef0b0e42f37f23624695b6ad0d229eb30085363f Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 8 Dec 2024 21:29:57 -0500 Subject: [PATCH 17/18] #5031: resolve some other minor issues --- plugins/pathable.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 0c8b45d205..293e64dc7f 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -242,7 +242,7 @@ static bool is_wagon_tile_traversible(df::tiletype tt) { auto special = tileSpecial(tt); auto material = tileMaterial(tt); - // Allow murky pool ramps + // Allow ramps (murky pool and river tiles are blocked except for ramps) if (shape == df::tiletype_shape::RAMP_TOP) return true; // NOTE: smoothing a boulder turns it into a smoothed floor @@ -300,9 +300,6 @@ static bool is_wagon_traversible(FloodCtx & ctx, const df::coord & pos, const df case tile_building_occ::Floored: // depot, lowered bridges or retractable bridges, forbidden hatches break; - default: - //NOTREACHED - break; } if (ctx.wgroup == Maps::getWalkableGroup(pos)) From 5d24e07d94d49c465e999161c6be04c2133cfad0 Mon Sep 17 00:00:00 2001 From: dhthwy <302825+dhthwy@users.noreply.github.com> Date: Sun, 8 Dec 2024 22:34:23 -0500 Subject: [PATCH 18/18] #5031: don't add non-edge tiles to entry_tiles --- plugins/pathable.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index 293e64dc7f..2e0e8d7e9a 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -173,11 +173,14 @@ static bool get_pathability_groups(color_ostream &out, unordered_set * static bool get_entry_tiles(unordered_set * entry_tiles, const unordered_set & depot_pathability_groups) { auto & edge = plotinfo->map_edge; size_t num_edge_tiles = edge.surface_x.size(); + uint32_t max_x, max_y, max_z; + Maps::getTileSize(max_x, max_y, max_z); bool found = false; for (size_t idx = 0; idx < num_edge_tiles; ++idx) { df::coord pos(edge.surface_x[idx], edge.surface_y[idx], edge.surface_z[idx]); auto wgroup = Maps::getWalkableGroup(pos); - if (depot_pathability_groups.contains(wgroup)) { + if (depot_pathability_groups.contains(wgroup) && + (pos.x == 0 || pos.y == 0 || pos.x == (int16_t)max_x || pos.y == (int16_t)max_y)) { found = true; if (!entry_tiles) break; @@ -372,11 +375,6 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat ctx.seen.emplace(depot_pos); ctx.search_edge.emplace(depot_pos); - auto & edge = plotinfo->map_edge; - size_t num_edge_tiles = edge.surface_x.size(); - int max_edge_x = edge.surface_x[num_edge_tiles - 1]; - int max_edge_y = edge.surface_y[num_edge_tiles - 1]; - while (!ctx.search_edge.empty()) { df::coord pos = ctx.search_edge.top(); ctx.search_edge.pop(); @@ -384,10 +382,7 @@ static bool wagon_flood(color_ostream &out, unordered_set * wagon_pat TRACE(log,out).print("checking tile: (%d, %d, %d); pathability group: %d\n", pos.x, pos.y, pos.z, Maps::getWalkableGroup(pos)); - // Ensure our wagon flood end points lands on an edge tile. - // When there is no path to the depot search_edge will not - // contain any edge tiles. - if ((pos.x == 0 || pos.y == 0 || pos.x == max_edge_x || pos.y == max_edge_y) && entry_tiles.contains(pos)) { + if (entry_tiles.contains(pos)) { found = true; if (!wagon_path) break;