From c8f590cbacefad8121216041ec215a597effc082 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 24 Mar 2023 14:36:06 -0700 Subject: [PATCH] allow player to choose any item when choosing items manually that is, ignore the global and building-specific filters --- docs/changelog.txt | 1 + plugins/buildingplan/buildingplan.cpp | 23 +++++---- plugins/buildingplan/buildingplan.h | 2 +- plugins/buildingplan/plannedbuilding.cpp | 2 +- plugins/lua/buildingplan/planneroverlay.lua | 57 +++++++++------------ 5 files changed, 38 insertions(+), 47 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 88c6eac3b..11d849e9b 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -43,6 +43,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `tailor`: now properly discriminates between dyed and undyed cloth, no longer defaults to using adamantine, and properly tracks material requirements for already queued orders ## Misc Improvements +- `buildingplan`: filters and global settings are now ignored when manually choosing items for a building - `stockpiles`: support applying stockpile configurations with fully enabled categories to stockpiles in worlds other than the one where the configuration was exported from - `stockpiles`: support partial application of a saved config based on dynamic filtering - `stockpiles`: additive and subtractive modes when applying a second stockpile configuration on top of a first diff --git a/plugins/buildingplan/buildingplan.cpp b/plugins/buildingplan/buildingplan.cpp index 1e2d2c80e..7f43f4a3c 100644 --- a/plugins/buildingplan/buildingplan.cpp +++ b/plugins/buildingplan/buildingplan.cpp @@ -424,7 +424,7 @@ static string getBucket(const df::job_item & ji, const PlannedBuilding & pb, int } // get a list of item vectors that we should search for matches -vector getVectorIds(color_ostream &out, const df::job_item *job_item) { +vector getVectorIds(color_ostream &out, const df::job_item *job_item, bool ignore_filters) { std::vector ret; // if the filter already has the vector_id set to something specific, use it @@ -440,13 +440,13 @@ vector getVectorIds(color_ostream &out, const df::job_it // which vectors to search if (job_item->flags2.bits.building_material) { - if (get_config_bool(config, CONFIG_BLOCKS)) + if (ignore_filters || get_config_bool(config, CONFIG_BLOCKS)) ret.push_back(df::job_item_vector_id::BLOCKS); - if (get_config_bool(config, CONFIG_BOULDERS)) + if (ignore_filters || get_config_bool(config, CONFIG_BOULDERS)) ret.push_back(df::job_item_vector_id::BOULDER); - if (get_config_bool(config, CONFIG_LOGS)) + if (ignore_filters || get_config_bool(config, CONFIG_LOGS)) ret.push_back(df::job_item_vector_id::WOOD); - if (get_config_bool(config, CONFIG_BARS)) + if (ignore_filters || get_config_bool(config, CONFIG_BARS)) ret.push_back(df::job_item_vector_id::BAR); } @@ -624,7 +624,7 @@ static void scheduleCycle(color_ostream &out) { } static int scanAvailableItems(color_ostream &out, df::building_type type, int16_t subtype, - int32_t custom, int index, vector *item_ids = NULL, + 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", @@ -639,7 +639,7 @@ static int scanAvailableItems(color_ostream &out, df::building_type type, int16_ auto &specials = item_filters.getSpecials(); auto &jitem = job_items[index]; - auto vector_ids = getVectorIds(out, jitem); + auto vector_ids = getVectorIds(out, jitem, ignore_filters); int count = 0; for (auto vector_id : vector_ids) { @@ -651,7 +651,8 @@ static int scanAvailableItems(color_ostream &out, df::building_type type, int16_ filter.setMaterialMask(0); filter.setMaterials(set()); } - if (itemPassesScreen(item) && matchesFilters(item, jitem, heat, filter, specials)) { + if (itemPassesScreen(item) && + (ignore_filters || matchesFilters(item, jitem, heat, filter, specials))) { if (item_ids) item_ids->emplace_back(item->id); if (counts) { @@ -680,7 +681,7 @@ static int getAvailableItems(lua_State *L) { "entering getAvailableItems building_type=%d subtype=%d custom=%d index=%d\n", type, subtype, custom, index); vector item_ids; - scanAvailableItems(*out, type, subtype, custom, index, &item_ids); + scanAvailableItems(*out, type, subtype, custom, index, true, &item_ids); Lua::PushVector(L, item_ids); return 1; } @@ -703,7 +704,7 @@ 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); + return scanAvailableItems(out, type, subtype, custom, index, false); } static bool hasFilter(color_ostream &out, df::building_type type, int16_t subtype, int32_t custom, int index) { @@ -871,7 +872,7 @@ static int getMaterialFilter(lua_State *L) { return 0; const auto &mat_filter = filters[index].getMaterials(); map counts; - scanAvailableItems(*out, type, subtype, custom, index, NULL, &counts); + scanAvailableItems(*out, type, subtype, custom, index, false, NULL, &counts); HeatSafety heat = get_heat_safety_filter(key); df::job_item jitem_cur_heat = getJobItemWithHeatSafety( get_job_items(*out, key)[index], heat); diff --git a/plugins/buildingplan/buildingplan.h b/plugins/buildingplan/buildingplan.h index 495602b0b..756a81f83 100644 --- a/plugins/buildingplan/buildingplan.h +++ b/plugins/buildingplan/buildingplan.h @@ -47,7 +47,7 @@ bool get_config_bool(DFHack::PersistentDataItem &c, int index); void set_config_val(DFHack::PersistentDataItem &c, int index, int value); void set_config_bool(DFHack::PersistentDataItem &c, int index, bool value); -std::vector getVectorIds(DFHack::color_ostream &out, const df::job_item *job_item); +std::vector getVectorIds(DFHack::color_ostream &out, const df::job_item *job_item, bool ignore_filters); bool itemPassesScreen(df::item * item); df::job_item getJobItemWithHeatSafety(const df::job_item *job_item, HeatSafety heat); bool matchesFilters(df::item * item, const df::job_item * job_item, HeatSafety heat, const ItemFilter &item_filter, const std::set &special); diff --git a/plugins/buildingplan/plannedbuilding.cpp b/plugins/buildingplan/plannedbuilding.cpp index 2be2cf26f..a20d7b29a 100644 --- a/plugins/buildingplan/plannedbuilding.cpp +++ b/plugins/buildingplan/plannedbuilding.cpp @@ -29,7 +29,7 @@ static vector> get_vector_ids(color_ostream &out, auto &jitems = bld->jobs[0]->job_items; int num_job_items = (int)jitems.size(); for (int jitem_idx = num_job_items - 1; jitem_idx >= 0; --jitem_idx) { - ret.emplace_back(getVectorIds(out, jitems[jitem_idx])); + ret.emplace_back(getVectorIds(out, jitems[jitem_idx], false)); } return ret; } diff --git a/plugins/lua/buildingplan/planneroverlay.lua b/plugins/lua/buildingplan/planneroverlay.lua index e92824f5f..7db3dc3a3 100644 --- a/plugins/lua/buildingplan/planneroverlay.lua +++ b/plugins/lua/buildingplan/planneroverlay.lua @@ -496,13 +496,6 @@ function PlannerOverlay:init() options={{label='Yes', value=true}, {label='No', value=false}}, initial_option=false, - enabled=function() - for idx = 1,4 do - if (self.subviews['item'..idx].available or 0) > 0 then - return true - end - end - end, on_change=function(choose) buildingplan.setChooseItems(uibs.building_type, uibs.building_subtype, uibs.custom_type, choose) end, @@ -678,7 +671,7 @@ function PlannerOverlay:onInput(keys) local filters = get_cur_filters() local num_filters = #filters local choose = self.subviews.choose - if choose.enabled() and choose:getOptionValue() then + if choose:getOptionValue() then local bounds = get_selected_bounds() self:save_placement() local is_hollow = self.subviews.hollow:getOptionValue() @@ -687,33 +680,29 @@ function PlannerOverlay:onInput(keys) df.global.game.main_interface.bottom_mode_selected = -1 for idx = num_filters,1,-1 do chosen_items[idx] = {} - if (self.subviews['item'..idx].available or 0) > 0 then - local filter = filters[idx] - active_screens[idx] = itemselection.ItemSelectionScreen{ - index=idx, - desc=require('plugins.buildingplan').get_desc(filter), - quantity=get_quantity(filter, is_hollow, bounds), - on_submit=function(items) - chosen_items[idx] = items - active_screens[idx]:dismiss() - active_screens[idx] = nil - pending = pending - 1 - if pending == 0 then - df.global.game.main_interface.bottom_mode_selected = df.main_bottom_mode_type.BUILDING_PLACEMENT - self:place_building(self:restore_placement(), chosen_items) - end - end, - on_cancel=function() - for i,scr in pairs(active_screens) do - scr:dismiss() - end + local filter = filters[idx] + active_screens[idx] = itemselection.ItemSelectionScreen{ + index=idx, + desc=require('plugins.buildingplan').get_desc(filter), + quantity=get_quantity(filter, is_hollow, bounds), + on_submit=function(items) + chosen_items[idx] = items + active_screens[idx]:dismiss() + active_screens[idx] = nil + pending = pending - 1 + if pending == 0 then df.global.game.main_interface.bottom_mode_selected = df.main_bottom_mode_type.BUILDING_PLACEMENT - self:restore_placement() - end, - }:show() - else - pending = pending - 1 - end + self:place_building(self:restore_placement(), chosen_items) + end + end, + on_cancel=function() + for i,scr in pairs(active_screens) do + scr:dismiss() + end + df.global.game.main_interface.bottom_mode_selected = df.main_bottom_mode_type.BUILDING_PLACEMENT + self:restore_placement() + end, + }:show() end else self:place_building(get_placement_data())