From f8de51aba3bd8710c59203e16bce50cb1f6e95ec Mon Sep 17 00:00:00 2001 From: silverflyone Date: Tue, 4 Apr 2023 03:08:43 +1000 Subject: [PATCH 1/5] Update Buildings.cpp Fixes #3159. Valid map coordinates from (0, 0, 0) to (world->map.x_count - 1, world->map.y_count - 1, world->map.z_count - 1). Stockpile coords (x1, y1, z) to (x2, y2, z) may lie outside of this region. Use min of (0, 0) and max of (world->map.x_count - 1, world->map.y_count - 1) when iterating the block. --- library/modules/Buildings.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 2b6fc8ec8..8a71485b2 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -1637,17 +1637,17 @@ StockpileIterator& StockpileIterator::operator++() { ++current; } else { // Start with the top-left block covering the stockpile. - block = Maps::getTileBlock(stockpile->x1, stockpile->y1, stockpile->z); + block = Maps::getTileBlock(std::min(std::max(stockpile->x1, 0), world->map.x_count-1), std::min(std::max(stockpile->y1, 0), world->map.y_count-1), stockpile->z); current = 0; } while (current >= block->items.size()) { // Out of items in this block; find the next block to search. - if (block->map_pos.x + 16 <= stockpile->x2) { - block = Maps::getTileBlock(block->map_pos.x + 16, block->map_pos.y, stockpile->z); + if (std::max(block->map_pos.x + 16, 0) <= std::min(std::max(stockpile->x2, 0), world->map.x_count-1)) { + block = Maps::getTileBlock(std::min(std::max(block->map_pos.x + 16, 0), world->map.x_count-1), block->map_pos.y, stockpile->z); current = 0; - } else if (block->map_pos.y + 16 <= stockpile->y2) { - block = Maps::getTileBlock(stockpile->x1, block->map_pos.y + 16, stockpile->z); + } else if (std::max(block->map_pos.y + 16, 0) <= std::min(std::max(stockpile->y2, 0), world->map.y_count-1)) { + block = Maps::getTileBlock(std::min(std::max(stockpile->x1, 0), world->map.x_count-1), std::min(std::max(block->map_pos.y + 16, 0), world->map.y_count-1), stockpile->z); current = 0; } else { // All items in all blocks have been checked. From 181f0bdf720f85f29c3c159b7f77d70b00dc22cc Mon Sep 17 00:00:00 2001 From: silverflyone Date: Tue, 4 Apr 2023 03:27:32 +1000 Subject: [PATCH 2/5] Update Buildings.cpp Boundary checks added. --- library/modules/Buildings.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 8a71485b2..172975e21 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -1635,6 +1635,12 @@ StockpileIterator& StockpileIterator::operator++() { if (block) { // Check the next item in the current block. ++current; + } + else if (stockpile->x2 < 0 || stockpile->y2 < 0 || stockpile->z < 0 || stockpile->x1 > world->map.x_count - 1 || stockpile->y1 > world->map.y_count - 1 || stockpile->z > world->map.z_count - 1) { + // if the stockpile bounds exist outside of valid map plane then no items can be in the stockpile + block = NULL; + item = NULL; + return *this; } else { // Start with the top-left block covering the stockpile. block = Maps::getTileBlock(std::min(std::max(stockpile->x1, 0), world->map.x_count-1), std::min(std::max(stockpile->y1, 0), world->map.y_count-1), stockpile->z); From 0cebad10785423cd5f6f3b854eb8594738eaed02 Mon Sep 17 00:00:00 2001 From: silverflyone Date: Wed, 5 Apr 2023 11:49:14 +1000 Subject: [PATCH 3/5] Update Buildings.cpp Removed extra min/max checks. --- library/modules/Buildings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 172975e21..23b3263f3 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -1649,11 +1649,11 @@ StockpileIterator& StockpileIterator::operator++() { while (current >= block->items.size()) { // Out of items in this block; find the next block to search. - if (std::max(block->map_pos.x + 16, 0) <= std::min(std::max(stockpile->x2, 0), world->map.x_count-1)) { - block = Maps::getTileBlock(std::min(std::max(block->map_pos.x + 16, 0), world->map.x_count-1), block->map_pos.y, stockpile->z); + if (block->map_pos.x + 16 <= std::min(stockpile->x2, world->map.x_count-1)) { + block = Maps::getTileBlock(block->map_pos.x + 16, block->map_pos.y, stockpile->z); current = 0; - } else if (std::max(block->map_pos.y + 16, 0) <= std::min(std::max(stockpile->y2, 0), world->map.y_count-1)) { - block = Maps::getTileBlock(std::min(std::max(stockpile->x1, 0), world->map.x_count-1), std::min(std::max(block->map_pos.y + 16, 0), world->map.y_count-1), stockpile->z); + } else if (block->map_pos.y + 16 <= std::min(stockpile->y2, world->map.y_count-1)) { + block = Maps::getTileBlock(std::max(stockpile->x1, 0), block->map_pos.y + 16, stockpile->z); current = 0; } else { // All items in all blocks have been checked. From d42d9ec6268ef7654c386a67b1ef9da9cd91b699 Mon Sep 17 00:00:00 2001 From: silverflyone Date: Wed, 5 Apr 2023 12:53:39 +1000 Subject: [PATCH 4/5] Update changelog.txt Fix log entry --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index ff9d05b0f..7cc0ed0c0 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,6 +39,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `hotkeys`: hotkey hints on menu popup will no longer get their last character cut off by the scrollbar - ``launchdf``: launch Dwarf Fortress via the Steam client so Steam Workshop is functional - `blueprint`: interpret saplings, shrubs, and twigs as floors instead of walls +- ``Buildings::StockpileIterator:``: fix to use world map boundaries when stockpile coordinates exist outside of the world map. Fixes unhandled exception for `combine`. ## Misc Improvements - `buildingplan`: items in the item selection dialog should now use the same item quality symbols as the base game From 7294678e2757f671ff44ffd88ef3655ca90c7920 Mon Sep 17 00:00:00 2001 From: Myk Date: Tue, 4 Apr 2023 22:42:58 -0700 Subject: [PATCH 5/5] Update docs/changelog.txt --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 7cc0ed0c0..7f3262099 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -39,7 +39,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `hotkeys`: hotkey hints on menu popup will no longer get their last character cut off by the scrollbar - ``launchdf``: launch Dwarf Fortress via the Steam client so Steam Workshop is functional - `blueprint`: interpret saplings, shrubs, and twigs as floors instead of walls -- ``Buildings::StockpileIterator:``: fix to use world map boundaries when stockpile coordinates exist outside of the world map. Fixes unhandled exception for `combine`. +- `combine`: fix error processing stockpiles with boundaries that extend outside of the map ## Misc Improvements - `buildingplan`: items in the item selection dialog should now use the same item quality symbols as the base game