Merge remote-tracking branches 'myk002/myk_buildingplan_no_quality' and 'myk002/myk_buildingplan_pause' into develop

develop
lethosor 2020-11-03 00:09:03 -05:00
commit 58079217d9
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
3 changed files with 91 additions and 31 deletions

@ -35,6 +35,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Fixes
- `buildingplan`: artifacts are now successfully matched when max quality is set to ``artifacts``
- `buildingplan`: no longer erroneously matches items to buildings while the game is paused
- `dwarfmonitor`: fixed a crash when opening the ``prefs`` screen if units have vague preferences
## Misc Improvements

@ -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<ViewscreenChooseMaterial>(*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();
@ -897,12 +931,19 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
return CR_OK;
}
static bool is_paused()
{
return World::ReadPauseState() ||
ui->main.mode > df::ui_sidebar_mode::Squads ||
!strict_virtual_cast<df::viewscreen_dwarfmodest>(Gui::getCurViewscreen(true));
}
static bool cycle_requested = false;
#define DAY_TICKS 1200
DFhackCExport command_result plugin_onupdate(color_ostream &)
{
if (Maps::IsValid() && !World::ReadPauseState()
if (Maps::IsValid() && !is_paused()
&& (cycle_requested || world->frame_counter % (DAY_TICKS/2) == 0))
{
planner.doCycle();

@ -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