From fbc26336cf763621f051484bb00bb479e297a220 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 31 Oct 2020 02:25:26 -0700 Subject: [PATCH] don't show quality properties for no-quality items for items that cannot have a quality or be decorated: in place mode, don't show quality adjustment hotkeys (or isDecorated flag hotkey) and don't interpret the associated keycodes if they are pressed. in query mode, don't show quality or decorated fields. --- plugins/buildingplan.cpp | 80 +++++++++++++++++++++++++----------- plugins/lua/buildingplan.lua | 32 +++++++++++---- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/plugins/buildingplan.cpp b/plugins/buildingplan.cpp index ad0bdf358..8b4c94493 100644 --- a/plugins/buildingplan.cpp +++ b/plugins/buildingplan.cpp @@ -313,6 +313,28 @@ static std::string get_item_label(const BuildingTypeKey &key, int item_idx) return s; } +static bool item_can_be_improved(const BuildingTypeKey &key, int item_idx) +{ + auto L = Lua::Core::State; + color_ostream_proxy out(Core::getInstance().getConsole()); + Lua::StackUnwinder top(L); + + if (!lua_checkstack(L, 5) || + !Lua::PushModulePublic( + out, L, "plugins.buildingplan", "item_can_be_improved")) + return false; + + Lua::Push(L, std::get<0>(key)); + Lua::Push(L, std::get<1>(key)); + Lua::Push(L, std::get<2>(key)); + Lua::Push(L, item_idx); + + if (!Lua::SafeCall(out, L, 4, 1)) + return false; + + return lua_toboolean(L, -1); +} + static bool construct_planned_building() { auto L = Lua::Core::State; @@ -466,13 +488,15 @@ struct buildingplan_query_hook : public df::viewscreen_dwarfmodest OutputString(COLOR_WHITE, x, y, item_label.c_str(), true, left_margin + 1); OutputString(COLOR_WHITE, x, y, get_item_label(toBuildingTypeKey(bld), filter_idx).c_str(), true, left_margin); ++y; - OutputString(COLOR_BROWN, x, y, "Min Quality: ", false, left_margin); - OutputString(COLOR_BLUE, x, y, filter.getMinQuality(), true, left_margin); - OutputString(COLOR_BROWN, x, y, "Max Quality: ", false, left_margin); - OutputString(COLOR_BLUE, x, y, filter.getMaxQuality(), true, left_margin); - - if (filter.getDecoratedOnly()) - OutputString(COLOR_BLUE, x, y, "Decorated Only", true, left_margin); + if (item_can_be_improved(toBuildingTypeKey(bld), filter_idx)) + { + OutputString(COLOR_BROWN, x, y, "Min Quality: ", false, left_margin); + OutputString(COLOR_BLUE, x, y, filter.getMinQuality(), true, left_margin); + OutputString(COLOR_BROWN, x, y, "Max Quality: ", false, left_margin); + OutputString(COLOR_BLUE, x, y, filter.getMaxQuality(), true, left_margin); + if (filter.getDecoratedOnly()) + OutputString(COLOR_BLUE, x, y, "Decorated Only", true, left_margin); + } OutputString(COLOR_BROWN, x, y, "Materials:", true, left_margin); auto filters = filter.getMaterials(); @@ -594,20 +618,27 @@ struct buildingplan_place_hook : public df::viewscreen_dwarfmodest return true; } + + if (input->count(interface_key::CUSTOM_SHIFT_M)) Screen::show(dts::make_unique(*filter), plugin_self); - else if (input->count(interface_key::CUSTOM_SHIFT_Q)) - filter->decMinQuality(); - else if (input->count(interface_key::CUSTOM_SHIFT_W)) - filter->incMinQuality(); - else if (input->count(interface_key::CUSTOM_SHIFT_A)) - filter->decMaxQuality(); - else if (input->count(interface_key::CUSTOM_SHIFT_S)) - filter->incMaxQuality(); - else if (input->count(interface_key::CUSTOM_SHIFT_D)) - filter->toggleDecoratedOnly(); + + if (item_can_be_improved(key, filter_idx)) + { + if (input->count(interface_key::CUSTOM_SHIFT_Q)) + filter->decMinQuality(); + else if (input->count(interface_key::CUSTOM_SHIFT_W)) + filter->incMinQuality(); + else if (input->count(interface_key::CUSTOM_SHIFT_A)) + filter->decMaxQuality(); + else if (input->count(interface_key::CUSTOM_SHIFT_S)) + filter->incMaxQuality(); + else if (input->count(interface_key::CUSTOM_SHIFT_D)) + filter->toggleDecoratedOnly(); + } + // ctrl+Right - else if (input->count(interface_key::A_MOVE_E_DOWN) && hasNextFilter()) + if (input->count(interface_key::A_MOVE_E_DOWN) && hasNextFilter()) { ++filter; --filter_idx; @@ -706,13 +737,16 @@ struct buildingplan_place_hook : public df::viewscreen_dwarfmodest OutputString(COLOR_WHITE, x, y, title.c_str(), true, left_margin + 1); OutputString(COLOR_WHITE, x, y, get_item_label(key, filter_idx).c_str(), true, left_margin); - OutputHotkeyString(x, y, "Min Quality: ", "QW"); - OutputString(COLOR_BROWN, x, y, filter->getMinQuality(), true, left_margin); + if (item_can_be_improved(key, filter_idx)) + { + OutputHotkeyString(x, y, "Min Quality: ", "QW"); + OutputString(COLOR_BROWN, x, y, filter->getMinQuality(), true, left_margin); - OutputHotkeyString(x, y, "Max Quality: ", "AS"); - OutputString(COLOR_BROWN, x, y, filter->getMaxQuality(), true, left_margin); + OutputHotkeyString(x, y, "Max Quality: ", "AS"); + OutputString(COLOR_BROWN, x, y, filter->getMaxQuality(), true, left_margin); - OutputToggleString(x, y, "Decorated Only", "D", filter->getDecoratedOnly(), true, left_margin); + OutputToggleString(x, y, "Decorated Only", "D", filter->getDecoratedOnly(), true, left_margin); + } OutputHotkeyString(x, y, "Material Filter:", "M", true, left_margin); auto filter_descriptions = filter->getMaterials(); diff --git a/plugins/lua/buildingplan.lua b/plugins/lua/buildingplan.lua index 73fe160fb..51a918afc 100644 --- a/plugins/lua/buildingplan.lua +++ b/plugins/lua/buildingplan.lua @@ -31,17 +31,20 @@ local function to_title_case(str) return str end +local function get_filter(btype, subtype, custom, reverse_idx) + local filters = dfhack.buildings.getFiltersByType( + {}, btype, subtype, custom) + if not filters or reverse_idx < 0 or reverse_idx >= #filters then + error(string.format('invalid index: %d', reverse_idx)) + end + return filters[#filters-reverse_idx] +end + -- returns a reasonable label for the item based on the qualities of the filter -- does not need the core suspended -- reverse_idx is 0-based and is expected to be counted from the *last* filter function get_item_label(btype, subtype, custom, reverse_idx) - local filters = dfhack.buildings.getFiltersByType( - {}, btype, subtype, custom) - if not filters then return 'No item' end - if reverse_idx < 0 or reverse_idx >= #filters then - return 'Invalid index' - end - local filter = filters[#filters-reverse_idx] + local filter = get_filter(btype, subtype, custom, reverse_idx) if filter.has_tool_use then return to_title_case(df.tool_uses[filter.has_tool_use]) end @@ -63,6 +66,21 @@ function get_item_label(btype, subtype, custom, reverse_idx) return "Unknown"; end +-- returns whether the items matched by the specified filter can have a quality +-- rating. This also conveniently indicates whether an item can be decorated. +-- does not need the core suspended +-- reverse_idx is 0-based and is expected to be counted from the *last* filter +function item_can_be_improved(btype, subtype, custom, reverse_idx) + local filter = get_filter(btype, subtype, custom, reverse_idx) + if filter.flags2 and filter.flags2.building_material then + return false; + end + return filter.item_type ~= df.item_type.WOOD and + filter.item_type ~= df.item_type.BLOCKS and + filter.item_type ~= df.item_type.BAR and + filter.item_type ~= df.item_type.BOULDER +end + -- needs the core suspended function construct_building_from_ui_state() local uibs = df.global.ui_build_selector