diff --git a/docs/changelog.txt b/docs/changelog.txt index b46eddc98..0121e9e5c 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -78,6 +78,7 @@ Template for new versions: - `sort`: added help button for squad assignment search/filter/sort - `zone`: animals trained for war or hunting are now labeled as such in animal assignment screens - `buildingplan`: support filtering cages by whether they are occupied +- `buildingplan`: show how many items you need to make when planning buildings ## Documentation - unavailable tools are no longer listed in the tag indices in the online docs diff --git a/plugins/buildingplan/buildingplan.cpp b/plugins/buildingplan/buildingplan.cpp index 540420749..9fb5641bb 100644 --- a/plugins/buildingplan/buildingplan.cpp +++ b/plugins/buildingplan/buildingplan.cpp @@ -677,7 +677,7 @@ static int scanAvailableItems(color_ostream &out, df::building_type type, int16_ int32_t custom, int index, bool ignore_filters, vector *item_ids = NULL, map *counts = NULL) { DEBUG(status,out).print( - "entering countAvailableItems building_type=%d subtype=%d custom=%d index=%d\n", + "entering scanAvailableItems building_type=%d subtype=%d custom=%d index=%d\n", type, subtype, custom, index); BuildingTypeKey key(type, subtype, custom); HeatSafety heat = get_heat_safety_filter(key); @@ -755,7 +755,30 @@ static int countAvailableItems(color_ostream &out, df::building_type type, int16 DEBUG(status,out).print( "entering countAvailableItems building_type=%d subtype=%d custom=%d index=%d\n", type, subtype, custom, index); - return scanAvailableItems(out, type, subtype, custom, index, false); + int count = scanAvailableItems(out, type, subtype, custom, index, false); + if (count) + return count; + + // nothing in stock; return how many are waiting in line as a negative + BuildingTypeKey key(type, subtype, custom); + auto &job_items = get_job_items(out, key); + if (index < 0 || job_items.size() <= (size_t)index) + return 0; + auto &jitem = job_items[index]; + + for (auto &entry : planned_buildings) { + auto &pb = entry.second; + // don't actually remove bad buildings from the list while we're + // actively iterating through that list + auto bld = pb.getBuildingIfValidOrRemoveIfNot(out, true); + if (!bld || bld->jobs.size() != 1) + continue; + for (auto pb_jitem : bld->jobs[0]->job_items) { + if (pb_jitem->item_type == jitem->item_type && pb_jitem->item_subtype == jitem->item_subtype) + count -= pb_jitem->quantity; + } + } + return count; } static bool hasFilter(color_ostream &out, df::building_type type, int16_t subtype, int32_t custom, int index) { diff --git a/plugins/lua/buildingplan/planneroverlay.lua b/plugins/lua/buildingplan/planneroverlay.lua index bdd0008f8..6241ff219 100644 --- a/plugins/lua/buildingplan/planneroverlay.lua +++ b/plugins/lua/buildingplan/planneroverlay.lua @@ -295,9 +295,12 @@ function ItemLine:get_item_line_text() if self.available >= quantity then self.note_pen = COLOR_GREEN self.note = ' Available now' + elseif self.available >= 0 then + self.note_pen = COLOR_BROWN + self.note = (' Will link next (need to make %d)'):format(quantity - self.available) else self.note_pen = COLOR_BROWN - self.note = ' Will link later' + self.note = (' Will link later (need to make %d)'):format(-self.available + quantity) end self.note = string.char(192) .. self.note -- character 192 is "└" @@ -318,7 +321,7 @@ function ItemLine:reduce_quantity(used_quantity) if not self.available then return end local filter = get_cur_filters()[self.idx] used_quantity = used_quantity or get_quantity(filter, self.is_hollow_fn()) - self.available = math.max(0, self.available - used_quantity) + self.available = self.available - used_quantity end local function get_placement_errors()