From 9cb1a45855751bfbab546ccb3249593c02019f82 Mon Sep 17 00:00:00 2001 From: Anuradha Dissanayake Date: Tue, 20 Nov 2012 23:12:11 +1300 Subject: [PATCH 01/35] Automaterial branch commit --- plugins/CMakeLists.txt | 1 + plugins/automaterial.cpp | 430 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 431 insertions(+) create mode 100644 plugins/automaterial.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 91d578215..5bda932ce 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -117,6 +117,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(regrass regrass.cpp) DFHACK_PLUGIN(forceequip forceequip.cpp) DFHACK_PLUGIN(manipulator manipulator.cpp) + DFHACK_PLUGIN(automaterial automaterial.cpp) # this one exports functions to lua DFHACK_PLUGIN(burrows burrows.cpp LINK_LIBRARIES lua) DFHACK_PLUGIN(sort sort.cpp LINK_LIBRARIES lua) diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp new file mode 100644 index 000000000..2e39f3411 --- /dev/null +++ b/plugins/automaterial.cpp @@ -0,0 +1,430 @@ +// Auto Material Select + +#include +#include +#include + +#include "Core.h" +#include +#include +#include +#include + + +// DF data structure definition headers +#include "DataDefs.h" +#include "MiscUtils.h" +#include "df/viewscreen_dwarfmodest.h" +#include "df/ui_build_selector.h" +#include "df/build_req_choice_genst.h" +#include "df/build_req_choice_specst.h" +#include "df/item.h" + +#include "df/ui.h" +#include "modules/Gui.h" +#include "modules/Screen.h" + +using std::map; +using std::string; +using std::vector; + +using namespace DFHack; +using namespace df::enums; +using df::global::gps; +using df::global::ui; +using df::global::ui_build_selector; + + +DFHACK_PLUGIN("automaterial"); + +struct MaterialDescriptor +{ + df::item_type item_type; + int16_t item_subtype; + int16_t type; + int32_t index; + bool valid; + + bool matches(const MaterialDescriptor &a) const + { + return a.valid && valid && + a.type == type && + a.index == index && + a.item_type == item_type && + a.item_subtype == item_subtype; + } +}; + +typedef int16_t construction_type; + +static map last_used_material; +static map last_moved_material; +static map< construction_type, vector > preferred_materials; +static map< construction_type, df::interface_key > hotkeys; +static bool last_used_moved = false; +static bool auto_choose_materials = true; +static bool auto_choose_attempted = true; +static bool revert_to_last_used_type = false; + +static command_result automaterial_cmd(color_ostream &out, vector & parameters) +{ + return CR_OK; +} + + +DFhackCExport command_result plugin_shutdown ( color_ostream &out ) +{ + return CR_OK; +} + + +void OutputString(int8_t color, int &x, int &y, const std::string &text, bool newline = false, int left_margin = 0) +{ + Screen::paintString(Screen::Pen(' ', color, 0), x, y, text); + if (newline) + { + ++y; + x = left_margin; + } + else + x += text.length(); +} + +void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, int left_margin = 0, int8_t color = COLOR_WHITE) +{ + OutputString(10, x, y, hotkey); + string display(": "); + display.append(text); + OutputString(color, x, y, display, newline, left_margin); +} + + +static inline bool in_material_choice_stage() +{ + return Gui::build_selector_hotkey(Core::getTopViewscreen()) && + ui->main.mode == ui_sidebar_mode::Build && + ui_build_selector->stage == 2; +} + +static inline bool in_type_choice_stage() +{ + return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && + ui->main.mode == ui_sidebar_mode::Build && + ui_build_selector && + ui_build_selector->building_type >= 0 && + ui_build_selector->stage == 1; +} + +static inline vector &get_curr_constr_prefs() +{ + if (preferred_materials.find(ui_build_selector->building_subtype) == preferred_materials.end()) + preferred_materials[ui_build_selector->building_subtype] = vector(); + + return preferred_materials[ui_build_selector->building_subtype]; +} + +static inline MaterialDescriptor &get_last_used_material() +{ + if (last_used_material.find(ui_build_selector->building_subtype) == last_used_material.end()) + last_used_material[ui_build_selector->building_subtype] = MaterialDescriptor(); + + return last_used_material[ui_build_selector->building_subtype]; +} + +static void set_last_used_material(MaterialDescriptor &matetial) +{ + last_used_material[ui_build_selector->building_subtype] = matetial; +} + +static MaterialDescriptor &get_last_moved_material() +{ + if (last_moved_material.find(ui_build_selector->building_subtype) == last_moved_material.end()) + last_moved_material[ui_build_selector->building_subtype] = MaterialDescriptor(); + + return last_moved_material[ui_build_selector->building_subtype]; +} + +static void set_last_moved_material(MaterialDescriptor &matetial) +{ + last_moved_material[ui_build_selector->building_subtype] = matetial; +} + +static MaterialDescriptor get_material_in_list(size_t i) +{ + MaterialDescriptor result; + result.valid = false; + + if (VIRTUAL_CAST_VAR(gen, df::build_req_choice_genst, ui_build_selector->choices[i])) + { + result.item_type = gen->item_type; + result.item_subtype = gen->item_subtype; + result.type = gen->mat_type; + result.index = gen->mat_index; + result.valid = true; + } + else if (VIRTUAL_CAST_VAR(spec, df::build_req_choice_specst, ui_build_selector->choices[i])) + { + result.item_type = gen->item_type; + result.item_subtype = gen->item_subtype; + result.type = spec->candidate->getActualMaterial(); + result.index = spec->candidate->getActualMaterialIndex(); + result.valid = true; + } + + return result; +} + + +static bool is_material_in_autoselect(size_t &i, MaterialDescriptor &material) +{ + for (i = 0; i < get_curr_constr_prefs().size(); i++) + { + if (get_curr_constr_prefs()[i].matches(material)) + return true; + } + + return false; +} + +static bool is_material_in_list(size_t &i, MaterialDescriptor &material) +{ + const size_t size = ui_build_selector->choices.size(); //Just because material list could be very big + for (i = 0; i < size; i++) + { + if (get_material_in_list(i).matches(material)) + return true; + } + + return false; +} + +static bool move_material_to_top(MaterialDescriptor &material) +{ + size_t i; + if (is_material_in_list(i, material)) + { + auto sel_item = ui_build_selector->choices[i]; + ui_build_selector->choices.erase(ui_build_selector->choices.begin() + i); + ui_build_selector->choices.insert(ui_build_selector->choices.begin(), sel_item); + + ui_build_selector->sel_index = 0; + set_last_moved_material(material); + return true; + } + + set_last_moved_material(MaterialDescriptor()); + return false; +} + +static bool choose_materials() +{ + size_t size = ui_build_selector->choices.size(); + for (size_t i = 0; i < size; i++) + { + MaterialDescriptor material = get_material_in_list(i); + size_t j; + if (is_material_in_autoselect(j, material)) + { + ui_build_selector->sel_index = i; + std::set< df::interface_key > keys; + keys.insert(df::interface_key::SELECT_ALL); + Core::getTopViewscreen()->feed(&keys); + if (!in_material_choice_stage()) + return true; + } + } + + return false; +} + +static bool check_autoselect(MaterialDescriptor &material, bool toggle) +{ + size_t idx; + if (is_material_in_autoselect(idx, material)) + { + if (toggle) + vector_erase_at(get_curr_constr_prefs(), idx); + + return true; + } + else + { + if (toggle) + get_curr_constr_prefs().push_back(material); + + return false; + } +} + +struct jobutils_hook : public df::viewscreen_dwarfmodest +{ + typedef df::viewscreen_dwarfmodest interpose_base; + + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) + { + if (in_material_choice_stage()) + { + MaterialDescriptor material = get_material_in_list(ui_build_selector->sel_index); + if (material.valid) + { + if (input->count(interface_key::SELECT) || input->count(interface_key::SEC_SELECT)) + { + if (get_last_moved_material().matches(material)) + last_used_moved = false; + + set_last_used_material(material); + } + else if (input->count(interface_key::CUSTOM_A)) + { + check_autoselect(material, true); + input->clear(); + } + } + } + else if (in_type_choice_stage()) + { + if (input->count(interface_key::CUSTOM_A)) + { + auto_choose_materials = !auto_choose_materials; + } + else if (input->count(interface_key::CUSTOM_T)) + { + revert_to_last_used_type = !revert_to_last_used_type; + } + } + + construction_type last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1; + INTERPOSE_NEXT(feed)(input); + + if (revert_to_last_used_type && last_used_constr_subtype >= 0 && !in_material_choice_stage()) + { + input->clear(); + std::set< df::interface_key > keys; + keys.insert(hotkeys[last_used_constr_subtype]); + Core::getTopViewscreen()->feed(&keys); + } + } + + DEFINE_VMETHOD_INTERPOSE(void, render, ()) + { + if (in_material_choice_stage()) + { + if (!last_used_moved) + { + if (auto_choose_materials && get_curr_constr_prefs().size() > 0) + { + last_used_moved = true; + if (choose_materials()) + { + return; + } + } + else if (ui_build_selector->is_grouped) + { + last_used_moved = true; + move_material_to_top(get_last_used_material()); + } + } + else if (!ui_build_selector->is_grouped) + { + last_used_moved = false; + } + } + else + { + last_used_moved = false; + } + + INTERPOSE_NEXT(render)(); + + if (in_material_choice_stage()) + { + MaterialDescriptor material = get_material_in_list(ui_build_selector->sel_index); + if (material.valid) + { + int left_margin = gps->dimx - 30; + int x = left_margin; + int y = 25; + + string toggle_string = "Enable"; + string title = "Disabled"; + if (check_autoselect(material, false)) + { + toggle_string = "Disable"; + title = "Enabled"; + } + + OutputString(COLOR_BROWN, x, y, "DFHack Autoselect: " + title, true, left_margin); + OutputHotkeyString(x, y, toggle_string.c_str(), "a", true, left_margin); + } + } + else if (in_type_choice_stage() && ui_build_selector->building_subtype != 7) + { + int left_margin = gps->dimx - 30; + int x = left_margin; + int y = 25; + + string autoselect_toggle_string = (auto_choose_materials) ? "Disable Auto Mat-select" : "Enable Auto Mat-select"; + string revert_toggle_string = (revert_to_last_used_type) ? "Disable Auto Type-select" : "Enable Auto Type-select"; + + OutputString(COLOR_BROWN, x, y, "DFHack Options", true, left_margin); + OutputHotkeyString(x, y, autoselect_toggle_string.c_str(), "a", true, left_margin); + OutputHotkeyString(x, y, revert_toggle_string.c_str(), "t", true, left_margin); + } + } +}; + +color_ostream_proxy console_out(Core::getInstance().getConsole()); + + +IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, render); + +DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) +{ + if (!gps || !INTERPOSE_HOOK(jobutils_hook, feed).apply() || !INTERPOSE_HOOK(jobutils_hook, render).apply()) + out.printerr("Could not insert jobutils hooks!\n"); + + hotkeys[1] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_WALL; + hotkeys[2] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_FLOOR; + hotkeys[6] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_RAMP; + hotkeys[3] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP; + hotkeys[4] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN; + hotkeys[5] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN; + hotkeys[0] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION; + hotkeys[7] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_TRACK; + hotkeys[5] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP; + + commands.push_back(PluginCommand( + "automaterial", "Makes construction easier by auto selecting materials", + automaterial_cmd, false, /* true means that the command can't be used from non-interactive user interface */ + // Extended help string. Used by CR_WRONG_USAGE and the help command: + " Makes construction easier by auto selecting materials.\n" + )); + return CR_OK; +} + + +/* +DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) +{ + switch (event) { + case SC_GAME_LOADED: + // initialize from the world just loaded + break; + case SC_GAME_UNLOADED: + // cleanup + break; + default: + break; + } + return CR_OK; +} +*/ + +/* +DFhackCExport command_result plugin_onupdate ( color_ostream &out ) +{ + return CR_OK; +} +*/ From ff40ef6d59e25b50985ebe3dddb169062cfe21e9 Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 20 Nov 2012 08:46:24 -0600 Subject: [PATCH 02/35] Run screenshots through pngout, shrinking them by about 50% --- images/assign-rack.png | Bin 8044 -> 3892 bytes images/guide-path.png | Bin 8224 -> 4871 bytes images/liquids.png | Bin 6473 -> 3676 bytes images/manipulator.png | Bin 12399 -> 7373 bytes images/mechanisms.png | Bin 6943 -> 3741 bytes images/power-meter.png | Bin 7523 -> 4435 bytes images/rename-bld.png | Bin 11008 -> 6667 bytes images/rename-prof.png | Bin 10174 -> 6190 bytes images/room-list.png | Bin 8562 -> 4839 bytes images/search.png | Bin 7283 -> 4509 bytes images/siege-engine.png | Bin 8227 -> 4023 bytes images/workflow-new1.png | Bin 9378 -> 5662 bytes images/workflow-new2.png | Bin 11397 -> 6862 bytes images/workflow.png | Bin 8206 -> 4931 bytes images/workshop-job-item.png | Bin 8297 -> 4806 bytes images/workshop-job-material.png | Bin 9278 -> 5553 bytes images/workshop-job.png | Bin 11076 -> 6461 bytes 17 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/assign-rack.png b/images/assign-rack.png index c0acb580230f15bdb265ace73f1f01d031dc8472..4ebcbf590e2e14ef74fa5c9896fa51205949686a 100644 GIT binary patch literal 3892 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 PU|{fc^>bP0l+XkK8|oCq literal 8044 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 literal 8224 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 Q0|Nttr>mdKI;Vst0De_hEdT%j literal 6473 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 Qz`(%Z>FVdQ&MBb@05i)pkpKVy diff --git a/images/manipulator.png b/images/manipulator.png index de61e30fc7c70fb0254e80d2abb0f0f5cfb9bae0..0a546034557fceb446aa0ccb8ddb51883fd71a84 100644 GIT binary patch literal 7373 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 E0BzTvv;Y7A diff --git a/images/mechanisms.png b/images/mechanisms.png index c46868449976403ad521a1b0a21c9c65187f41d1..062d126cd4f0899ffc307ed0deb5389836f3d049 100644 GIT binary patch literal 3741 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 diff --git a/images/power-meter.png b/images/power-meter.png index 4d84f3761bf1f003130b8dde92534b12bfc2cfe6..b1a4b6229d6dfa72535d52566b81342007edc615 100644 GIT binary patch literal 4435 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 Q7#J8lUHx3vIVCg!0D_32<^TWy literal 7523 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 diff --git a/images/rename-bld.png b/images/rename-bld.png index e1fa8ef31592ca83469e7a675f93b306ef5507f0..0028a87a5b9e68ac28e1b4d4bfdf2fe666ea6583 100644 GIT binary patch literal 6667 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 F0sy)v$Atg@ literal 11008 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 diff --git a/images/rename-prof.png b/images/rename-prof.png index 789f6fe6f7dc51f52e5266609a8a7fa29a34db2d..5f2cfc4532a01158970addec96fe21f0eb258cfd 100644 GIT binary patch literal 6190 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 z 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 E0As=BzyJUM diff --git a/images/room-list.png b/images/room-list.png index 34c93591a4e56d50413c37c3244fa7729207cc99..5a60398f8db7575307fd19d91ac0b1a8795869aa 100644 GIT binary patch literal 4839 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 literal 8562 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 X?3ekwvCy7@fq}u()z4*}Q$iB}%~?UN diff --git a/images/search.png b/images/search.png index f299622fc00fd581ee7ecc5b7e9539222a83366a..384c3c533214d92769818d9d357293208a11e507 100644 GIT binary patch literal 4509 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 literal 8227 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 literal 9378 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

)DSzR^kjS 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 diff --git a/images/workflow-new2.png b/images/workflow-new2.png index 94456331608f732d8164db160c9d01cbc818a84a..74a4922be1e7e337676bbd4e8b2c028267f7b1f7 100644 GIT binary patch literal 6862 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 literal 8206 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 E0NG@HYybcN diff --git a/images/workshop-job-item.png b/images/workshop-job-item.png index 952f19ae00733dd764f606421d8e1ee3a9f53ae2..cef6919186c8e324a9354e4ee7d3884caa16341f 100644 GIT binary patch literal 4806 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 literal 8297 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 diff --git a/images/workshop-job-material.png b/images/workshop-job-material.png index 2ad69eaf4ac2b128d0fd234f192d87a3bfdf9cbe..d75797766290f13d41dc202dd07e2a1a085cbd29 100644 GIT binary patch literal 5553 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 literal 9278 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 Date: Tue, 20 Nov 2012 21:15:09 +0100 Subject: [PATCH 03/35] ruby: update map_tile.mat_info for soil/stone special cases --- plugins/ruby/map.rb | 62 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/plugins/ruby/map.rb b/plugins/ruby/map.rb index 7c616d722..e9500efa3 100644 --- a/plugins/ruby/map.rb +++ b/plugins/ruby/map.rb @@ -159,8 +159,8 @@ module DFHack v.inorganic_mat if v end - # return the world_data.geo_biome for current tile - def geo_biome + # return the RegionMapEntry (from designation.biome) + def region_map_entry b = designation.biome wd = df.world.world_data @@ -174,7 +174,12 @@ module DFHack ry -= 1 if b < 3 and ry > 0 ry += 1 if b > 5 and ry < wd.world_height-1 - wd.geo_biomes[ wd.region_map[rx][ry].geo_index ] + wd.region_map[rx][ry] + end + + # return the world_data.geo_biome for current tile + def geo_biome + df.world.world_data.geo_biomes[ region_map_entry.geo_index ] end # return the world_data.geo_biome.layer for current tile @@ -182,14 +187,53 @@ module DFHack geo_biome.layers[designation.geolayer_index] end - # current tile mat_index (vein if applicable, or base material) - def mat_index - mat_index_vein or stone_layer.mat_index + # MaterialInfo: token for current tile, based on tilemat (vein, soil, plant, lava_stone...) + def mat_info + case tilemat + when :SOIL + base = stone_layer + if !df.world.raws.inorganics[base.mat_index].flags[:SOIL_ANY] + base = geo_biome.layers.find_all { |l| df.world.raws.inorganics[l.mat_index].flags[:SOIL_ANY] }.last + end + mat_index = (base ? base.mat_index : rand(df.world.raws.inorganics.length)) + MaterialInfo.new(0, mat_index) + + when :STONE + base = stone_layer + if df.world.raws.inorganics[base.mat_index].flags[:SOIL_ANY] + base = geo_biome.layers.find { |l| !df.world.raws.inorganics[l.mat_index].flags[:SOIL_ANY] } + end + mat_index = (base ? base.mat_index : rand(df.world.raws.inorganics.length)) + MaterialInfo.new(0, mat_index) + + when :MINERAL + mat_index = (mat_index_vein || stone_layer.mat_index) + MaterialInfo.new(0, mat_index) + + when :LAVA_STONE + # XXX this is wrong + # maybe should search world.region_details.pos == biome_region_pos ? + idx = mapblock.region_offset[designation.biome] + mat_index = df.world.world_data.region_details[idx].lava_stone + MaterialInfo.new(0, mat_index) + + # TODO + #when :PLANT + #when :GRASS_DARK, :GRASS_DEAD, :GRASS_DRY, :GRASS_LIGHT + #when :FEATURE + #when :FROZEN_LIQUID + #when :CONSTRUCTION + else # AIR ASHES BROOK CAMPFIRE DRIFTWOOD FIRE HFS MAGMA POOL RIVER + MaterialInfo.new(-1, -1) + end end - # MaterialInfo: inorganic token for current tile - def mat_info - MaterialInfo.new(0, mat_index) + def mat_type + mat_info.mat_type + end + + def mat_index + mat_info.mat_index end def inspect From 0d9efec062f4fd63e46266e1cfecde7d726c11df Mon Sep 17 00:00:00 2001 From: Anuradha Dissanayake Date: Wed, 21 Nov 2012 20:17:36 +1300 Subject: [PATCH 04/35] Disable plugin in non construction menu --- plugins/automaterial.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp index 2e39f3411..d05e13a3e 100644 --- a/plugins/automaterial.cpp +++ b/plugins/automaterial.cpp @@ -102,19 +102,28 @@ void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bo static inline bool in_material_choice_stage() { return Gui::build_selector_hotkey(Core::getTopViewscreen()) && + ui_build_selector->building_type == df::building_type::Construction && ui->main.mode == ui_sidebar_mode::Build && ui_build_selector->stage == 2; } -static inline bool in_type_choice_stage() +static inline bool in_placement_stage() { return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && ui->main.mode == ui_sidebar_mode::Build && ui_build_selector && - ui_build_selector->building_type >= 0 && + ui_build_selector->building_type == df::building_type::Construction && ui_build_selector->stage == 1; } +static inline bool in_type_choice_stage() +{ + return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && + ui->main.mode == ui_sidebar_mode::Build && + ui_build_selector && + ui_build_selector->building_type < 0; +} + static inline vector &get_curr_constr_prefs() { if (preferred_materials.find(ui_build_selector->building_subtype) == preferred_materials.end()) @@ -281,7 +290,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest } } } - else if (in_type_choice_stage()) + else if (in_placement_stage()) { if (input->count(interface_key::CUSTOM_A)) { @@ -358,7 +367,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest OutputHotkeyString(x, y, toggle_string.c_str(), "a", true, left_margin); } } - else if (in_type_choice_stage() && ui_build_selector->building_subtype != 7) + else if (in_placement_stage() && ui_build_selector->building_subtype != 7) { int left_margin = gps->dimx - 30; int x = left_margin; From 2a83d9229094eb38628c422ede9d1b28495cd8ec Mon Sep 17 00:00:00 2001 From: Anuradha Dissanayake Date: Wed, 21 Nov 2012 23:45:26 +1300 Subject: [PATCH 05/35] Code cleanup --- plugins/automaterial.cpp | 124 ++++++++++++++------------------------- 1 file changed, 45 insertions(+), 79 deletions(-) diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp index d05e13a3e..ac5a4ae22 100644 --- a/plugins/automaterial.cpp +++ b/plugins/automaterial.cpp @@ -14,13 +14,14 @@ // DF data structure definition headers #include "DataDefs.h" #include "MiscUtils.h" -#include "df/viewscreen_dwarfmodest.h" -#include "df/ui_build_selector.h" #include "df/build_req_choice_genst.h" #include "df/build_req_choice_specst.h" +#include "df/construction_type.h" #include "df/item.h" - #include "df/ui.h" +#include "df/ui_build_selector.h" +#include "df/viewscreen_dwarfmodest.h" + #include "modules/Gui.h" #include "modules/Screen.h" @@ -34,7 +35,6 @@ using df::global::gps; using df::global::ui; using df::global::ui_build_selector; - DFHACK_PLUGIN("automaterial"); struct MaterialDescriptor @@ -55,12 +55,10 @@ struct MaterialDescriptor } }; -typedef int16_t construction_type; - -static map last_used_material; -static map last_moved_material; -static map< construction_type, vector > preferred_materials; -static map< construction_type, df::interface_key > hotkeys; +static map last_used_material; +static map last_moved_material; +static map< int16_t, vector > preferred_materials; +static map< int16_t, df::interface_key > hotkeys; static bool last_used_moved = false; static bool auto_choose_materials = true; static bool auto_choose_attempted = true; @@ -71,7 +69,6 @@ static command_result automaterial_cmd(color_ostream &out, vector & par return CR_OK; } - DFhackCExport command_result plugin_shutdown ( color_ostream &out ) { return CR_OK; @@ -183,7 +180,6 @@ static MaterialDescriptor get_material_in_list(size_t i) return result; } - static bool is_material_in_autoselect(size_t &i, MaterialDescriptor &material) { for (i = 0; i < get_curr_constr_prefs().size(); i++) @@ -225,27 +221,6 @@ static bool move_material_to_top(MaterialDescriptor &material) return false; } -static bool choose_materials() -{ - size_t size = ui_build_selector->choices.size(); - for (size_t i = 0; i < size; i++) - { - MaterialDescriptor material = get_material_in_list(i); - size_t j; - if (is_material_in_autoselect(j, material)) - { - ui_build_selector->sel_index = i; - std::set< df::interface_key > keys; - keys.insert(df::interface_key::SELECT_ALL); - Core::getTopViewscreen()->feed(&keys); - if (!in_material_choice_stage()) - return true; - } - } - - return false; -} - static bool check_autoselect(MaterialDescriptor &material, bool toggle) { size_t idx; @@ -269,6 +244,27 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; + bool choose_materials() + { + size_t size = ui_build_selector->choices.size(); + for (size_t i = 0; i < size; i++) + { + MaterialDescriptor material = get_material_in_list(i); + size_t j; + if (is_material_in_autoselect(j, material)) + { + ui_build_selector->sel_index = i; + std::set< df::interface_key > keys; + keys.insert(df::interface_key::SELECT_ALL); + this->feed(&keys); + if (!in_material_choice_stage()) + return true; + } + } + + return false; + } + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { if (in_material_choice_stage()) @@ -302,15 +298,17 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest } } - construction_type last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1; + int16_t last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1; INTERPOSE_NEXT(feed)(input); - if (revert_to_last_used_type && last_used_constr_subtype >= 0 && !in_material_choice_stage()) + if (revert_to_last_used_type && + last_used_constr_subtype >= 0 && + !in_material_choice_stage() && + hotkeys.find(last_used_constr_subtype) != hotkeys.end()) { input->clear(); - std::set< df::interface_key > keys; - keys.insert(hotkeys[last_used_constr_subtype]); - Core::getTopViewscreen()->feed(&keys); + input->insert(hotkeys[last_used_constr_subtype]); + this->feed(input); } } @@ -394,46 +392,14 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector Date: Wed, 21 Nov 2012 14:56:41 +0400 Subject: [PATCH 06/35] Add a couple of screenshots for tweaks, and comment on example config keys. --- NEWS | 6 +-- Readme.html | 79 +++++++++++++++++++++++-------------- Readme.rst | 44 +++++++++++++++------ images/tweak-mil-color.png | Bin 0 -> 6967 bytes images/tweak-plate.png | Bin 0 -> 3365 bytes 5 files changed, 85 insertions(+), 44 deletions(-) create mode 100644 images/tweak-mil-color.png create mode 100644 images/tweak-plate.png diff --git a/NEWS b/NEWS index 2cde6ba68..f14bcb1b4 100644 --- a/NEWS +++ b/NEWS @@ -10,13 +10,13 @@ DFHack future - fastdwarf: new mode using debug flags, and some internal consistency fixes. - added a small stand-alone utility for applying and removing binary patches. - removebadthoughts: add --dry-run option - New tweaks: - - tweak military-training: speed up melee squad training up to 10x (depends on unit count). - superdwarf: work in adventure mode too + New tweaks: + - tweak military-training: speed up melee squad training up to 10x (normally 3-5x). New scripts: - binpatch: the same as the stand-alone binpatch.exe, but works at runtime. - region-pops: displays animal populations of the region and allows tweaking them. - - lua: lua interpreter. + - lua: lua interpreter front-end converted to a script from a native command. - dfusion: misc scripts with a text based menu. - embark: lets you embark anywhere. New GUI scripts: diff --git a/Readme.html b/Readme.html index 137971abd..f520e1a82 100644 --- a/Readme.html +++ b/Readme.html @@ -1840,43 +1840,55 @@ they are scuttled. -stable-cursor:Saves the exact cursor position between t/q/k/d/etc menus of dwarfmode. +stable-cursor:

Saves the exact cursor position between t/q/k/d/etc menus of dwarfmode.

+ -patrol-duty:Makes Train orders not count as patrol duty to stop unhappy thoughts. -Does NOT fix the problem when soldiers go off-duty (i.e. civilian). +patrol-duty:

Makes Train orders not count as patrol duty to stop unhappy thoughts. +Does NOT fix the problem when soldiers go off-duty (i.e. civilian).

+ readable-build-plate: - Fixes rendering of creature weight limits in pressure plate build menu. + 

Fixes rendering of creature weight limits in pressure plate build menu.

+images/tweak-plate.png + -stable-temp:Fixes performance bug 6012 by squashing jitter in temperature updates. -In very item-heavy forts with big stockpiles this can improve FPS by 50-100% +stable-temp:

Fixes performance bug 6012 by squashing jitter in temperature updates. +In very item-heavy forts with big stockpiles this can improve FPS by 50-100%

+ -fast-heat:Further improves temperature update performance by ensuring that 1 degree +fast-heat:

Further improves temperature update performance by ensuring that 1 degree of item temperature is crossed in no more than specified number of frames when updating from the environment temperature. This reduces the time it -takes for stable-temp to stop updates again when equilibrium is disturbed. +takes for stable-temp to stop updates again when equilibrium is disturbed.

+ -fix-dimensions:Fixes subtracting small amount of thread/cloth/liquid from a stack +fix-dimensions:

Fixes subtracting small amount of thread/cloth/liquid from a stack by splitting the stack and subtracting from the remaining single item. -This is a necessary addition to the binary patch in bug 808. +This is a necessary addition to the binary patch in bug 808.

+ advmode-contained: - Works around bug 6202, i.e. custom reactions with container inputs + 

Works around bug 6202, i.e. custom reactions with container inputs in advmode. The issue is that the screen tries to force you to select the contents separately from the container. This forcefully skips child -reagents. +reagents.

+ -fast-trade:Makes Shift-Enter in the Move Goods to Depot and Trade screens select -the current item (fully, in case of a stack), and scroll down one line. +fast-trade:

Makes Shift-Enter in the Move Goods to Depot and Trade screens select +the current item (fully, in case of a stack), and scroll down one line.

+ military-stable-assign: - Preserve list order and cursor position when assigning to squad, + 

Preserve list order and cursor position when assigning to squad, i.e. stop the rightmost list of the Positions page of the military -screen from constantly resetting to the top. +screen from constantly resetting to the top.

+ military-color-assigned: - Color squad candidates already assigned to other squads in brown/green -to make them stand out more in the list. + 

Color squad candidates already assigned to other squads in yellow/green +to make them stand out more in the list.

+images/tweak-mil-color.png + @@ -2826,14 +2838,14 @@ key while search is active clears the search instead of executing the trade.

gui/liquids

-

To use, bind to a key and activate in the 'k' mode.

+

To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode.

images/liquids.png

While active, use the suggested keys to switch the usual liquids parameters, and Enter to select the target area and apply changes.

gui/mechanisms

-

To use, bind to a key and activate in the 'q' mode.

+

To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode.

images/mechanisms.png

Lists mechanisms connected to the building, and their links. Navigating the list centers the view on the relevant linked buildings.

@@ -2861,18 +2873,21 @@ their species string.

The building or unit options are automatically assumed when in relevant ui state.

+

The example config binds building/unit rename to Ctrl-Shift-N, and +unit profession change to Ctrl-Shift-T.

gui/room-list

-

To use, bind to a key and activate in the 'q' mode, either immediately or after opening -the assign owner page.

+

To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, +either immediately or after opening the assign owner page.

images/room-list.png

The script lists other rooms owned by the same owner, or by the unit selected in the assign list, and allows unassigning them.

gui/choose-weapons

-

Bind to a key, and activate in the Equip->View/Customize page of the military screen.

+

Bind to a key (the example config uses Ctrl-W), and activate in the Equip->View/Customize +page of the military screen.

Depending on the cursor location, it rewrites all 'individual choice weapon' entries in the selected squad or position to use a specific weapon type matching the assigned unit's top skill. If the cursor is in the rightmost list over a weapon entry, it rewrites @@ -2882,14 +2897,16 @@ and may lead to inappropriate weapons being selected.

gui/guide-path

-

Bind to a key, and activate in the Hauling menu with the cursor over a Guide order.

+

Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with +the cursor over a Guide order.

images/guide-path.png

The script displays the cached path that will be used by the order; the game computes it when the order is executed for the first time.

gui/workshop-job

-

Bind to a key, and activate with a job selected in a workshop in the 'q' mode.

+

Bind to a key (the example config uses Alt-A), and activate with a job selected in +a workshop in the 'q' mode.

images/workshop-job.png

The script shows a list of the input reagents of the selected job, and allows changing them like the job item-type and job item-material commands.

@@ -2924,7 +2941,8 @@ you have to unset the material first.

gui/workflow

-

Bind to a key, and activate with a job selected in a workshop in the 'q' mode.

+

Bind to a key (the example config uses Alt-W), and activate with a job selected +in a workshop in the 'q' mode.

images/workflow.png

This script provides a simple interface to constraints managed by the workflow plugin. When active, it displays a list of all constraints applicable to the @@ -2953,7 +2971,8 @@ suit your need, and set the item count range.

gui/assign-rack

-

Bind to a key, and activate when viewing a weapon rack in the 'q' mode.

+

Bind to a key (the example config uses P), and activate when viewing a weapon +rack in the 'q' mode.

images/assign-rack.png

This script is part of a group of related fixes to make the armory storage work again. The existing issues are:

@@ -3002,7 +3021,8 @@ e.g. like making siegers bring their own, are something only Toady can do.

Configuration UI

The configuration front-end to the plugin is implemented by the gui/siege-engine -script. Bind it to a key and activate after selecting a siege engine in 'q' mode.

+script. Bind it to a key (the example config uses Alt-A) and activate after selecting +a siege engine in 'q' mode.

images/siege-engine.png

The main mode displays the current target, selected ammo item type, linked stockpiles and the allowed operator skill range. The map tile color is changed to signify if it can be @@ -3026,7 +3046,8 @@ menu.

The power-meter plugin implements a modified pressure plate that detects power being supplied to gear boxes built in the four adjacent N/S/W/E tiles.

The configuration front-end is implemented by the gui/power-meter script. Bind it to a -key and activate after selecting Pressure Plate in the build menu.

+key (the example config uses Ctrl-Shift-M) and activate after selecting Pressure Plate +in the build menu.

images/power-meter.png

The script follows the general look and feel of the regular pressure plate build configuration page, but configures parameters relevant to the modded power meter building.

diff --git a/Readme.rst b/Readme.rst index 4488490dd..1f5ac08fd 100644 --- a/Readme.rst +++ b/Readme.rst @@ -1077,6 +1077,9 @@ Subcommands that persist until disabled or DF quit: :patrol-duty: Makes Train orders not count as patrol duty to stop unhappy thoughts. Does NOT fix the problem when soldiers go off-duty (i.e. civilian). :readable-build-plate: Fixes rendering of creature weight limits in pressure plate build menu. + + .. image:: images/tweak-plate.png + :stable-temp: Fixes performance bug 6012 by squashing jitter in temperature updates. In very item-heavy forts with big stockpiles this can improve FPS by 50-100% :fast-heat: Further improves temperature update performance by ensuring that 1 degree @@ -1095,9 +1098,16 @@ Subcommands that persist until disabled or DF quit: :military-stable-assign: Preserve list order and cursor position when assigning to squad, i.e. stop the rightmost list of the Positions page of the military screen from constantly resetting to the top. -:military-color-assigned: Color squad candidates already assigned to other squads in brown/green +:military-color-assigned: Color squad candidates already assigned to other squads in yellow/green to make them stand out more in the list. + .. image:: images/tweak-mil-color.png + +:military-training: Speeds up melee squad training by removing an almost certainly + unintended inverse dependency of training speed on unit count + (i.e. the more units you have, the slower it becomes), and making + the units spar more. + fix-armory ---------- @@ -2039,7 +2049,7 @@ key while search is active clears the search instead of executing the trade. gui/liquids =========== -To use, bind to a key and activate in the 'k' mode. +To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode. .. image:: images/liquids.png @@ -2050,7 +2060,7 @@ to select the target area and apply changes. gui/mechanisms ============== -To use, bind to a key and activate in the 'q' mode. +To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode. .. image:: images/mechanisms.png @@ -2088,12 +2098,15 @@ via a simple dialog in the game ui. The ``building`` or ``unit`` options are automatically assumed when in relevant ui state. +The example config binds building/unit rename to Ctrl-Shift-N, and +unit profession change to Ctrl-Shift-T. + gui/room-list ============= -To use, bind to a key and activate in the 'q' mode, either immediately or after opening -the assign owner page. +To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, +either immediately or after opening the assign owner page. .. image:: images/room-list.png @@ -2104,7 +2117,8 @@ list, and allows unassigning them. gui/choose-weapons ================== -Bind to a key, and activate in the Equip->View/Customize page of the military screen. +Bind to a key (the example config uses Ctrl-W), and activate in the Equip->View/Customize +page of the military screen. Depending on the cursor location, it rewrites all 'individual choice weapon' entries in the selected squad or position to use a specific weapon type matching the assigned @@ -2118,7 +2132,8 @@ and may lead to inappropriate weapons being selected. gui/guide-path ============== -Bind to a key, and activate in the Hauling menu with the cursor over a Guide order. +Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with +the cursor over a Guide order. .. image:: images/guide-path.png @@ -2129,7 +2144,8 @@ computes it when the order is executed for the first time. gui/workshop-job ================ -Bind to a key, and activate with a job selected in a workshop in the 'q' mode. +Bind to a key (the example config uses Alt-A), and activate with a job selected in +a workshop in the 'q' mode. .. image:: images/workshop-job.png @@ -2176,7 +2192,8 @@ you have to unset the material first. gui/workflow ============ -Bind to a key, and activate with a job selected in a workshop in the 'q' mode. +Bind to a key (the example config uses Alt-W), and activate with a job selected +in a workshop in the 'q' mode. .. image:: images/workflow.png @@ -2217,7 +2234,8 @@ If you don't need advanced settings, you can just press 'y' to confirm creation. gui/assign-rack =============== -Bind to a key, and activate when viewing a weapon rack in the 'q' mode. +Bind to a key (the example config uses P), and activate when viewing a weapon +rack in the 'q' mode. .. image:: images/assign-rack.png @@ -2278,7 +2296,8 @@ Configuration UI ---------------- The configuration front-end to the plugin is implemented by the gui/siege-engine -script. Bind it to a key and activate after selecting a siege engine in 'q' mode. +script. Bind it to a key (the example config uses Alt-A) and activate after selecting +a siege engine in 'q' mode. .. image:: images/siege-engine.png @@ -2310,7 +2329,8 @@ The power-meter plugin implements a modified pressure plate that detects power b supplied to gear boxes built in the four adjacent N/S/W/E tiles. The configuration front-end is implemented by the gui/power-meter script. Bind it to a -key and activate after selecting Pressure Plate in the build menu. +key (the example config uses Ctrl-Shift-M) and activate after selecting Pressure Plate +in the build menu. .. image:: images/power-meter.png diff --git a/images/tweak-mil-color.png b/images/tweak-mil-color.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a012cabf69fe7ab62d0941dcd018f946c86eab GIT binary patch literal 6967 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 Z%(P0}8tz6dJPVrj@^tlcS?83{1OUt@y|VxS literal 0 HcmV?d00001 diff --git a/images/tweak-plate.png b/images/tweak-plate.png new file mode 100644 index 0000000000000000000000000000000000000000..b7ba2c88d4781010cd7a118863bd324b1ab89757 GIT binary patch literal 3365 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 XRpQq0=1>r*f5YJE>gTe~DWM4fx0lup literal 0 HcmV?d00001 From 5f92561cd9ad9045d754cdc602734c69d4ed55fa Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 22 Nov 2012 02:57:55 +0100 Subject: [PATCH 07/35] add scripts/lever, add binary patches section in NEWS file --- NEWS | 9 ++++ scripts/lever.rb | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 scripts/lever.rb diff --git a/NEWS b/NEWS index f14bcb1b4..e12608d34 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ DFHack future - lua: lua interpreter front-end converted to a script from a native command. - dfusion: misc scripts with a text based menu. - embark: lets you embark anywhere. + - lever: list and pull fort levers from the dfhack console. New GUI scripts: - gui/guide-path: displays the cached path for minecart Guide orders. - gui/workshop-job: displays inputs of a workshop job and allows tweaking them. @@ -26,6 +27,14 @@ DFHack future - gui/assign-rack: works together with a binary patch to fix weapon racks. - gui/gm-editor: an universal editor for lots of dfhack things. - gui/companion-order: a adventure mode command interface for your companions. + New binary patches: + - armorstand-capacity + - custom-reagent-size + - deconstruct-heapfall + - deconstruct-teleport + - hospital-overstocking + - training-ammo + - weaponrack-unassign Workflow plugin: - properly considers minecarts assigned to routes busy. - code for deducing job outputs rewritten in lua for flexibility. diff --git a/scripts/lever.rb b/scripts/lever.rb new file mode 100644 index 000000000..2012f7297 --- /dev/null +++ b/scripts/lever.rb @@ -0,0 +1,109 @@ +# control your levers from the dfhack console + +def lever_pull_job(bld) + ref = DFHack::GeneralRefBuildingHolderst.cpp_new + ref.building_id = bld.id + + job = DFHack::Job.cpp_new + job.job_type = :PullLever + job.pos = [bld.centerx, bld.centery, bld.z] + job.general_refs << ref + bld.jobs << job + df.job_link job +end + +def lever_pull_cheat(bld) + bld.state = (bld.state == 0 ? 1 : 0) + + bld.linked_mechanisms.each { |i| + i.general_refs.grep(DFHack::GeneralRefBuildingHolderst).each { |r| + tg = r.building_tg + next if tg.gate_flags.closing or tg.gate_flags.opening + r.building_tg.setTriggerState(tg.gate_flags.closed ? 0 : 1) + } + } + + puts lever_descr(bld) +end + +def lever_descr(bld, idx=nil) + ret = [] + + # lever description + descr = '' + descr << "#{idx}: " if idx + descr << "lever ##{bld.id} @[#{bld.centerx}, #{bld.centery}, #{bld.z}] #{bld.state == 0 ? '\\' : '/'}" + + bld.linked_mechanisms.map { |i| + i.general_refs.grep(DFHack::GeneralRefBuildingHolderst) + }.flatten.each { |r| + # linked building description + tg = r.building_tg + state = tg.gate_flags.closed ? 'closed' : 'opened' + state << ', closing' if tg.gate_flags.closing + state << ', opening' if tg.gate_flags.opening + + ret << (descr + " linked to #{tg._rtti_classname} ##{tg.id} @[#{tg.centerx}, #{tg.centery}, #{tg.z}] #{state}") + + # indent other links + descr = descr.gsub(/./, ' ') + } + + ret << descr if ret.empty? + + ret +end + +def lever_list + @lever_list = [] + df.world.buildings.other[:TRAP].find_all { |bld| + bld.trap_type == :Lever + }.sort_by { |bld| bld.id }.each { |bld| + puts lever_descr(bld, @lever_list.length) + @lever_list << bld.id + } +end + +case $script_args[0] +when 'pull' + cheat = $script_args.delete('--cheat') || $script_args.delete('--now') + + id = $script_args[1].to_i + id = @lever_list[id] || id + bld = df.building_find(id) + raise 'invalid lever id' if not bld + + if cheat + lever_pull_cheat(bld) + else + lever_pull_job(bld) + end + +when 'list' + lever_list + +when /^\d+$/ + id = $script_args[0].to_i + id = @lever_list[id] || id + bld = df.building_find(id) + raise 'invalid lever id' if not bld + + puts lever_descr(bld) + +else + puts < Date: Thu, 22 Nov 2012 03:17:41 +0100 Subject: [PATCH 08/35] script/lever: synchronize linked buildings as the game does --- scripts/lever.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/lever.rb b/scripts/lever.rb index 2012f7297..2c7735146 100644 --- a/scripts/lever.rb +++ b/scripts/lever.rb @@ -13,16 +13,14 @@ def lever_pull_job(bld) end def lever_pull_cheat(bld) - bld.state = (bld.state == 0 ? 1 : 0) - bld.linked_mechanisms.each { |i| i.general_refs.grep(DFHack::GeneralRefBuildingHolderst).each { |r| - tg = r.building_tg - next if tg.gate_flags.closing or tg.gate_flags.opening - r.building_tg.setTriggerState(tg.gate_flags.closed ? 0 : 1) + r.building_tg.setTriggerState(bld.state) } } + bld.state = (bld.state == 0 ? 1 : 0) + puts lever_descr(bld) end From e7905a5cff2b6174d92527ab6bbdd8358b98b877 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 22 Nov 2012 19:38:45 +0400 Subject: [PATCH 09/35] Add docs for the automaterial plugin, and use the new Painter class. --- NEWS | 3 + Readme.html | 123 ++++++++++++++++++++----------- Readme.rst | 39 ++++++++++ images/automaterial-mat.png | Bin 0 -> 5187 bytes images/automaterial-pos.png | Bin 0 -> 3007 bytes library/include/modules/Screen.h | 4 + plugins/automaterial.cpp | 69 ++++++----------- 7 files changed, 147 insertions(+), 91 deletions(-) create mode 100644 images/automaterial-mat.png create mode 100644 images/automaterial-pos.png diff --git a/NEWS b/NEWS index e12608d34..6ba9a769f 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,9 @@ DFHack future properly designated barracks be used again for storage of squad equipment. New Search plugin by falconne: Adds an incremental search function to the Stocks, Trading and Unit List screens. + New AutoMaterial plugin by falconne: + Makes building constructions (walls, floors, fortifications, etc) a little bit easier by + saving you from having to trawl through long lists of materials each time you place one. Dfusion plugin: Reworked to make use of lua modules, now all the scripts can be used from other scripts. diff --git a/Readme.html b/Readme.html index f520e1a82..5b231b429 100644 --- a/Readme.html +++ b/Readme.html @@ -508,33 +508,34 @@ access DF memory and allow for easier development of new tools.

  • In-game interface tools
  • -
  • Behavior Mods
  • @@ -2836,15 +2846,42 @@ are actually visible in the list; the same effect applies to the Trade Value numbers displayed by the screen. Because of this, pressing the 't' key while search is active clears the search instead of executing the trade.

    +
    +

    AutoMaterial

    +

    The automaterial plugin makes building constructions (walls, floors, fortifications, +etc) a little bit easier by saving you from having to trawl through long lists of +materials each time you place one.

    +

    Firstly, it moves the last used material for a given construction type to the top of +the list, if there are any left. So if you build a wall with chalk blocks, the next +time you place a wall the chalk blocks will be at the top of the list, regardless of +distance (it only does this in "grouped" mode, as individual item lists could be huge). +This should mean you can place most constructions without having to search for your +preferred material type.

    +images/automaterial-mat.png +

    Pressing 'a' while highlighting any material will enable that material for "auto select" +for this construction type. You can enable multiple materials as autoselect. Now the next +time you place this type of construction, the plugin will automatically choose materials +for you from the kinds you enabled. If there is enough to satisfy the whole placement, +you won't be prompted with the material screen - the construction will be placed and you +will be back in the construction menu as if you did it manually.

    +

    When choosing the construction placement, you will see a couple of options:

    +images/automaterial-pos.png +

    Use 'a' here to temporarily disable the material autoselection, e.g. if you need +to go to the material selection screen so you can toggle some materials on or off.

    +

    The other option (auto type selection, off by default) can be toggled on with 't'. If you +toggle this option on, instead of returning you to the main construction menu after selecting +materials, it returns you back to this screen. If you use this along with several autoselect +enabled materials, you should be able to place complex constructions more conveniently.

    +
    -

    gui/liquids

    +

    gui/liquids

    To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode.

    images/liquids.png

    While active, use the suggested keys to switch the usual liquids parameters, and Enter to select the target area and apply changes.

    -

    gui/mechanisms

    +

    gui/mechanisms

    To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode.

    images/mechanisms.png

    Lists mechanisms connected to the building, and their links. Navigating the list centers @@ -2854,7 +2891,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter re-entering the mechanisms ui.

    -

    gui/rename

    +

    gui/rename

    Backed by the rename plugin, this script allows entering the desired name via a simple dialog in the game ui.

      @@ -2877,7 +2914,7 @@ their species string.

      unit profession change to Ctrl-Shift-T.

    -

    gui/room-list

    +

    gui/room-list

    To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, either immediately or after opening the assign owner page.

    images/room-list.png @@ -2885,7 +2922,7 @@ either immediately or after opening the assign owner page.

    list, and allows unassigning them.

    -

    gui/choose-weapons

    +

    gui/choose-weapons

    Bind to a key (the example config uses Ctrl-W), and activate in the Equip->View/Customize page of the military screen.

    Depending on the cursor location, it rewrites all 'individual choice weapon' entries @@ -2896,7 +2933,7 @@ only that entry, and does it even if it is not 'individual choice'.

    and may lead to inappropriate weapons being selected.

    -

    gui/guide-path

    +

    gui/guide-path

    Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with the cursor over a Guide order.

    images/guide-path.png @@ -2904,7 +2941,7 @@ the cursor over a Guide order.

    computes it when the order is executed for the first time.

    -

    gui/workshop-job

    +

    gui/workshop-job

    Bind to a key (the example config uses Alt-A), and activate with a job selected in a workshop in the 'q' mode.

    images/workshop-job.png @@ -2940,7 +2977,7 @@ and then try to change the input item type, now it won't let you select plan you have to unset the material first.

    -

    gui/workflow

    +

    gui/workflow

    Bind to a key (the example config uses Alt-W), and activate with a job selected in a workshop in the 'q' mode.

    images/workflow.png @@ -2970,7 +3007,7 @@ suit your need, and set the item count range.

    If you don't need advanced settings, you can just press 'y' to confirm creation.

    -

    gui/assign-rack

    +

    gui/assign-rack

    Bind to a key (the example config uses P), and activate when viewing a weapon rack in the 'q' mode.

    images/assign-rack.png @@ -2995,7 +3032,7 @@ of currently assigned racks for every valid squad.

    -

    Behavior Mods

    +

    Behavior Mods

    These plugins, when activated via configuration UI or by detecting certain structures in RAWs, modify the game engine behavior concerning the target objects to add features not otherwise present.

    @@ -3006,20 +3043,20 @@ technical challenge, and do not represent any long-term plans to produce more similar modifications of the game.

    -

    Siege Engine

    +

    Siege Engine

    The siege-engine plugin enables siege engines to be linked to stockpiles, and aimed at an arbitrary rectangular area across Z levels, instead of the original four directions. Also, catapults can be ordered to load arbitrary objects, not just stones.

    -

    Rationale

    +

    Rationale

    Siege engines are a very interesting feature, but sadly almost useless in the current state because they haven't been updated since 2D and can only aim in four directions. This is an attempt to bring them more up to date until Toady has time to work on it. Actual improvements, e.g. like making siegers bring their own, are something only Toady can do.

    -

    Configuration UI

    +

    Configuration UI

    The configuration front-end to the plugin is implemented by the gui/siege-engine script. Bind it to a key (the example config uses Alt-A) and activate after selecting a siege engine in 'q' mode.

    @@ -3042,7 +3079,7 @@ menu.

    -

    Power Meter

    +

    Power Meter

    The power-meter plugin implements a modified pressure plate that detects power being supplied to gear boxes built in the four adjacent N/S/W/E tiles.

    The configuration front-end is implemented by the gui/power-meter script. Bind it to a @@ -3053,11 +3090,11 @@ in the build menu.

    configuration page, but configures parameters relevant to the modded power meter building.

    -

    Steam Engine

    +

    Steam Engine

    The steam-engine plugin detects custom workshops with STEAM_ENGINE in their token, and turns them into real steam engines.

    -

    Rationale

    +

    Rationale

    The vanilla game contains only water wheels and windmills as sources of power, but windmills give relatively little power, and water wheels require flowing water, which must either be a real river and thus immovable and @@ -3068,7 +3105,7 @@ it can be done just by combining existing features of the game engine in a new way with some glue code and a bit of custom logic.

    -

    Construction

    +

    Construction

    The workshop needs water as its input, which it takes via a passable floor tile below it, like usual magma workshops do. The magma version also needs magma.

    @@ -3092,7 +3129,7 @@ short axles that can be built later than both of the engines.

    -

    Operation

    +

    Operation

    In order to operate the engine, queue the Stoke Boiler job (optionally on repeat). A furnace operator will come, possibly bringing a bar of fuel, and perform it. As a result, a "boiling water" item will appear @@ -3123,7 +3160,7 @@ decrease it by further 4%, and also decrease the whole steam use rate by 10%.

    -

    Explosions

    +

    Explosions

    The engine must be constructed using barrel, pipe and piston from fire-safe, or in the magma version magma-safe metals.

    During operation weak parts get gradually worn out, and @@ -3132,7 +3169,7 @@ toppled during operation by a building destroyer, or a tantruming dwarf.

    -

    Save files

    +

    Save files

    It should be safe to load and view engine-using fortresses from a DF version without DFHack installed, except that in such case the engines won't work. However actually making modifications @@ -3143,7 +3180,7 @@ being generated.

    -

    Add Spatter

    +

    Add Spatter

    This plugin makes reactions with names starting with SPATTER_ADD_ produce contaminants on the items instead of improvements. The produced contaminants are immune to being washed away by water or destroyed by diff --git a/Readme.rst b/Readme.rst index 1f5ac08fd..e6554cac0 100644 --- a/Readme.rst +++ b/Readme.rst @@ -1968,6 +1968,9 @@ are mostly implemented by lua scripts. In order to avoid user confusion, as a matter of policy all these tools display the word "DFHack" on the screen somewhere while active. + When that is not appropriate because they merely add keybinding hints to + existing DF screens, they deliberately use red instead of green for the key. + As an exception, the tweak plugin described above does not follow this guideline because it arguably just fixes small usability bugs in the game UI. @@ -2046,6 +2049,42 @@ Value numbers displayed by the screen. Because of this, pressing the 't' key while search is active clears the search instead of executing the trade. +AutoMaterial +============ + +The automaterial plugin makes building constructions (walls, floors, fortifications, +etc) a little bit easier by saving you from having to trawl through long lists of +materials each time you place one. + +Firstly, it moves the last used material for a given construction type to the top of +the list, if there are any left. So if you build a wall with chalk blocks, the next +time you place a wall the chalk blocks will be at the top of the list, regardless of +distance (it only does this in "grouped" mode, as individual item lists could be huge). +This should mean you can place most constructions without having to search for your +preferred material type. + +.. image:: images/automaterial-mat.png + +Pressing 'a' while highlighting any material will enable that material for "auto select" +for this construction type. You can enable multiple materials as autoselect. Now the next +time you place this type of construction, the plugin will automatically choose materials +for you from the kinds you enabled. If there is enough to satisfy the whole placement, +you won't be prompted with the material screen - the construction will be placed and you +will be back in the construction menu as if you did it manually. + +When choosing the construction placement, you will see a couple of options: + +.. image:: images/automaterial-pos.png + +Use 'a' here to temporarily disable the material autoselection, e.g. if you need +to go to the material selection screen so you can toggle some materials on or off. + +The other option (auto type selection, off by default) can be toggled on with 't'. If you +toggle this option on, instead of returning you to the main construction menu after selecting +materials, it returns you back to this screen. If you use this along with several autoselect +enabled materials, you should be able to place complex constructions more conveniently. + + gui/liquids =========== diff --git a/images/automaterial-mat.png b/images/automaterial-mat.png new file mode 100644 index 0000000000000000000000000000000000000000..5517bbc6d33636b9842da1b712cac161a74a4f39 GIT binary patch literal 5187 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 W)^K<4+PMr23=E#GelF{r5}E+j7abe` literal 0 HcmV?d00001 diff --git a/images/automaterial-pos.png b/images/automaterial-pos.png new file mode 100644 index 0000000000000000000000000000000000000000..959573643a8d8a0ba3e9c686dd80e1885f4ad318 GIT binary patch literal 3007 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 V?6>&l$-uzC;OXk;vd$@?2>{cX3o-xz literal 0 HcmV?d00001 diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 2c245ae4c..bfc393734 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -28,7 +28,9 @@ distribution. #include "BitArray.h" #include "ColorText.h" #include "Types.h" + #include +#include #include "DataDefs.h" #include "df/graphic.h" @@ -51,6 +53,8 @@ namespace DFHack { class Core; + typedef std::set interface_key_set; + /** * The Screen module * \ingroup grp_modules diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp index ac5a4ae22..9f383b935 100644 --- a/plugins/automaterial.cpp +++ b/plugins/automaterial.cpp @@ -74,28 +74,6 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) return CR_OK; } - -void OutputString(int8_t color, int &x, int &y, const std::string &text, bool newline = false, int left_margin = 0) -{ - Screen::paintString(Screen::Pen(' ', color, 0), x, y, text); - if (newline) - { - ++y; - x = left_margin; - } - else - x += text.length(); -} - -void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, int left_margin = 0, int8_t color = COLOR_WHITE) -{ - OutputString(10, x, y, hotkey); - string display(": "); - display.append(text); - OutputString(color, x, y, display, newline, left_margin); -} - - static inline bool in_material_choice_stage() { return Gui::build_selector_hotkey(Core::getTopViewscreen()) && @@ -137,7 +115,7 @@ static inline MaterialDescriptor &get_last_used_material() return last_used_material[ui_build_selector->building_subtype]; } -static void set_last_used_material(MaterialDescriptor &matetial) +static void set_last_used_material(const MaterialDescriptor &matetial) { last_used_material[ui_build_selector->building_subtype] = matetial; } @@ -150,7 +128,7 @@ static MaterialDescriptor &get_last_moved_material() return last_moved_material[ui_build_selector->building_subtype]; } -static void set_last_moved_material(MaterialDescriptor &matetial) +static void set_last_moved_material(const MaterialDescriptor &matetial) { last_moved_material[ui_build_selector->building_subtype] = matetial; } @@ -306,9 +284,9 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest !in_material_choice_stage() && hotkeys.find(last_used_constr_subtype) != hotkeys.end()) { - input->clear(); - input->insert(hotkeys[last_used_constr_subtype]); - this->feed(input); + interface_key_set keys; + keys.insert(hotkeys[last_used_constr_subtype]); + INTERPOSE_NEXT(feed)(&keys); } } @@ -349,47 +327,42 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest MaterialDescriptor material = get_material_in_list(ui_build_selector->sel_index); if (material.valid) { - int left_margin = gps->dimx - 30; - int x = left_margin; - int y = 25; - - string toggle_string = "Enable"; string title = "Disabled"; if (check_autoselect(material, false)) { - toggle_string = "Disable"; title = "Enabled"; } - OutputString(COLOR_BROWN, x, y, "DFHack Autoselect: " + title, true, left_margin); - OutputHotkeyString(x, y, toggle_string.c_str(), "a", true, left_margin); + auto dims = Gui::getDwarfmodeViewDims(); + Screen::Painter dc(dims.menu()); + + dc.seek(1,24).key_pen(COLOR_LIGHTRED).pen(COLOR_WHITE); + dc.key(interface_key::CUSTOM_A).string(": Autoselect "+title); } } - else if (in_placement_stage() && ui_build_selector->building_subtype != 7) + else if (in_placement_stage() && ui_build_selector->building_subtype < construction_type::TrackN) { - int left_margin = gps->dimx - 30; - int x = left_margin; - int y = 25; + string autoselect_toggle = (auto_choose_materials) ? "Disable" : "Enable"; + string revert_toggle = (revert_to_last_used_type) ? "Disable" : "Enable"; - string autoselect_toggle_string = (auto_choose_materials) ? "Disable Auto Mat-select" : "Enable Auto Mat-select"; - string revert_toggle_string = (revert_to_last_used_type) ? "Disable Auto Type-select" : "Enable Auto Type-select"; + auto dims = Gui::getDwarfmodeViewDims(); + Screen::Painter dc(dims.menu()); - OutputString(COLOR_BROWN, x, y, "DFHack Options", true, left_margin); - OutputHotkeyString(x, y, autoselect_toggle_string.c_str(), "a", true, left_margin); - OutputHotkeyString(x, y, revert_toggle_string.c_str(), "t", true, left_margin); + dc.seek(1,23).key_pen(COLOR_LIGHTRED).pen(COLOR_WHITE); + dc.key(interface_key::CUSTOM_A).string(": "+autoselect_toggle+" Auto Mat-Select").newline(1); + dc.key(interface_key::CUSTOM_T).string(": "+revert_toggle+" Auto Type-Select"); } } }; -color_ostream_proxy console_out(Core::getInstance().getConsole()); - - IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, feed); IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, render); DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) { - if (!gps || !INTERPOSE_HOOK(jobutils_hook, feed).apply() || !INTERPOSE_HOOK(jobutils_hook, render).apply()) + if (!gps || !ui_build_selector || + !INTERPOSE_HOOK(jobutils_hook, feed).apply() || + !INTERPOSE_HOOK(jobutils_hook, render).apply()) out.printerr("Could not insert jobutils hooks!\n"); hotkeys[construction_type::Wall] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_WALL; From 2a0d04804068a3e63866fa128711a0d1c2add8b4 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 22 Nov 2012 20:08:47 +0400 Subject: [PATCH 10/35] Make tweak stable-cursor interact with the build menu properly. --- NEWS | 1 + plugins/tweak.cpp | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 6ba9a769f..463ebb47a 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ DFHack future - added a small stand-alone utility for applying and removing binary patches. - removebadthoughts: add --dry-run option - superdwarf: work in adventure mode too + - tweak stable-cursor: carries cursor location from/to Build menu. New tweaks: - tweak military-training: speed up melee squad training up to 10x (normally 3-5x). New scripts: diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp index 7143e715e..70d915ffc 100644 --- a/plugins/tweak.cpp +++ b/plugins/tweak.cpp @@ -212,15 +212,31 @@ struct stable_cursor_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; + bool check_default() + { + switch (ui->main.mode) { + case ui_sidebar_mode::Default: + return true; + + case ui_sidebar_mode::Build: + return ui_build_selector && + (ui_build_selector->building_type < 0 || + ui_build_selector->stage < 1); + + default: + return false; + } + } + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { - bool was_default = (ui->main.mode == df::ui_sidebar_mode::Default); + bool was_default = check_default(); df::coord view = Gui::getViewportPos(); df::coord cursor = Gui::getCursorPos(); INTERPOSE_NEXT(feed)(input); - bool is_default = (ui->main.mode == df::ui_sidebar_mode::Default); + bool is_default = check_default(); df::coord cur_cursor = Gui::getCursorPos(); if (is_default && !was_default) @@ -241,7 +257,7 @@ struct stable_cursor_hook : df::viewscreen_dwarfmodest tmp.insert(interface_key::CURSOR_UP_Z); INTERPOSE_NEXT(feed)(&tmp); } - else if (cur_cursor.isValid()) + else if (!is_default && cur_cursor.isValid()) { last_cursor = df::coord(); } From e3eb325d3680aa06b5fa0cde68da186345858e34 Mon Sep 17 00:00:00 2001 From: Quietust Date: Fri, 23 Nov 2012 19:18:56 -0600 Subject: [PATCH 11/35] Minimize references to gps->dimx/dimy --- library/modules/Screen.cpp | 45 ++++++++++++++------------ plugins/manipulator.cpp | 66 ++++++++++++++++++++------------------ plugins/search.cpp | 8 +++-- 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index f2d1f2d5d..cd20bc25e 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -110,10 +110,10 @@ bool Screen::paintTile(const Pen &pen, int x, int y) { if (!gps || !pen.valid()) return false; - int dimx = gps->dimx, dimy = gps->dimy; - if (x < 0 || x >= dimx || y < 0 || y >= dimy) return false; + auto dim = getWindowSize(); + if (x < 0 || x >= dim.x || y < 0 || y >= dim.y) return false; - doSetTile(pen, x*dimy + y); + doSetTile(pen, x*dim.y + y); return true; } @@ -121,11 +121,11 @@ Pen Screen::readTile(int x, int y) { if (!gps) return Pen(0,0,0,-1); - int dimx = gps->dimx, dimy = gps->dimy; - if (x < 0 || x >= dimx || y < 0 || y >= dimy) + auto dim = getWindowSize(); + if (x < 0 || x >= dim.x || y < 0 || y >= dim.y) return Pen(0,0,0,-1); - int index = x*dimy + y; + int index = x*dim.y + y; auto screen = gps->screen + index*4; if (screen[3] & 0x80) return Pen(0,0,0,-1); @@ -154,14 +154,15 @@ Pen Screen::readTile(int x, int y) bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text) { - if (!gps || y < 0 || y >= gps->dimy) return false; + auto dim = getWindowSize(); + if (!gps || y < 0 || y >= dim.y) return false; Pen tmp(pen); bool ok = false; for (size_t i = -std::min(0,x); i < text.size(); i++) { - if (x + i >= size_t(gps->dimx)) + if (x + i >= size_t(dim.x)) break; tmp.ch = text[i]; @@ -175,17 +176,18 @@ bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text) bool Screen::fillRect(const Pen &pen, int x1, int y1, int x2, int y2) { + auto dim = getWindowSize(); if (!gps || !pen.valid()) return false; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; - if (x2 >= gps->dimx) x2 = gps->dimx-1; - if (y2 >= gps->dimy) y2 = gps->dimy-1; + if (x2 >= dim.x) x2 = dim.x-1; + if (y2 >= dim.y) y2 = dim.y-1; if (x1 > x2 || y1 > y2) return false; for (int x = x1; x <= x2; x++) { - int index = x*gps->dimy; + int index = x*dim.y; for (int y = y1; y <= y2; y++) doSetTile(pen, index+y); @@ -198,32 +200,33 @@ bool Screen::drawBorder(const std::string &title) { if (!gps) return false; - int dimx = gps->dimx, dimy = gps->dimy; + auto dim = getWindowSize(); Pen border('\xDB', 8); Pen text(0, 0, 7); Pen signature(0, 0, 8); - for (int x = 0; x < dimx; x++) + for (int x = 0; x < dim.x; x++) { - doSetTile(border, x * dimy + 0); - doSetTile(border, x * dimy + dimy - 1); + doSetTile(border, x * dim.y + 0); + doSetTile(border, x * dim.y + dim.y - 1); } - for (int y = 0; y < dimy; y++) + for (int y = 0; y < dim.y; y++) { - doSetTile(border, 0 * dimy + y); - doSetTile(border, (dimx - 1) * dimy + y); + doSetTile(border, 0 * dim.y + y); + doSetTile(border, (dim.x - 1) * dim.y + y); } - paintString(signature, dimx-8, dimy-1, "DFHack"); + paintString(signature, dim.x-8, dim.y-1, "DFHack"); - return paintString(text, (dimx - title.length()) / 2, 0, title); + return paintString(text, (dim.x - title.length()) / 2, 0, title); } bool Screen::clear() { if (!gps) return false; - return fillRect(Pen(' ',0,0,false), 0, 0, gps->dimx-1, gps->dimy-1); + auto dim = getWindowSize(); + return fillRect(Pen(' ',0,0,false), 0, 0, dim.x-1, dim.y-1); } bool Screen::invalidate() diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 79999d468..59b257979 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -456,11 +456,13 @@ void viewscreen_unitlaborsst::refreshNames() void viewscreen_unitlaborsst::calcSize() { - num_rows = gps->dimy - 10; + auto dim = Screen::getWindowSize(); + + num_rows = dim.y - 10; if (num_rows > units.size()) num_rows = units.size(); - int num_columns = gps->dimx - DISP_COLUMN_MAX - 1; + int num_columns = dim.x - DISP_COLUMN_MAX - 1; // min/max width of columns int col_minwidth[DISP_COLUMN_MAX]; @@ -940,10 +942,11 @@ void viewscreen_unitlaborsst::render() dfhack_viewscreen::render(); + auto dim = Screen::getWindowSize(); + Screen::clear(); Screen::drawBorder(" Dwarf Manipulator - Manage Labors "); - Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_HAPPINESS], 2, "Hap."); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_NAME], 2, "Name"); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_PROFESSION], 2, "Profession"); @@ -1116,48 +1119,48 @@ void viewscreen_unitlaborsst::render() canToggle = (cur->allowEdit) && (columns[sel_column].labor != unit_labor::NONE); } - int x = 2; - OutputString(10, x, gps->dimy - 3, Screen::getKeyDisplay(interface_key::SELECT)); - OutputString(canToggle ? 15 : 8, x, gps->dimy - 3, ": Toggle labor, "); + int x = 2, y = dim.y - 3; + OutputString(10, x, dim.y - 3, Screen::getKeyDisplay(interface_key::SELECT)); + OutputString(canToggle ? 15 : 8, x, y, ": Toggle labor, "); - OutputString(10, x, gps->dimy - 3, Screen::getKeyDisplay(interface_key::SELECT_ALL)); - OutputString(canToggle ? 15 : 8, x, gps->dimy - 3, ": Toggle Group, "); + OutputString(10, x, dim.y - 3, Screen::getKeyDisplay(interface_key::SELECT_ALL)); + OutputString(canToggle ? 15 : 8, x, y, ": Toggle Group, "); - OutputString(10, x, gps->dimy - 3, Screen::getKeyDisplay(interface_key::UNITJOB_VIEW)); - OutputString(15, x, gps->dimy - 3, ": ViewCre, "); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::UNITJOB_VIEW)); + OutputString(15, x, y, ": ViewCre, "); - OutputString(10, x, gps->dimy - 3, Screen::getKeyDisplay(interface_key::UNITJOB_ZOOM_CRE)); - OutputString(15, x, gps->dimy - 3, ": Zoom-Cre"); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::UNITJOB_ZOOM_CRE)); + OutputString(15, x, y, ": Zoom-Cre"); - x = 2; - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::LEAVESCREEN)); - OutputString(15, x, gps->dimy - 2, ": Done, "); + x = 2; y = dim.y - 2; + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::LEAVESCREEN)); + OutputString(15, x, y, ": Done, "); - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::SECONDSCROLL_DOWN)); - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::SECONDSCROLL_UP)); - OutputString(15, x, gps->dimy - 2, ": Sort by Skill, "); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SECONDSCROLL_DOWN)); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SECONDSCROLL_UP)); + OutputString(15, x, y, ": Sort by Skill, "); - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::SECONDSCROLL_PAGEDOWN)); - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::SECONDSCROLL_PAGEUP)); - OutputString(15, x, gps->dimy - 2, ": Sort by ("); - OutputString(10, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::CHANGETAB)); - OutputString(15, x, gps->dimy - 2, ") "); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SECONDSCROLL_PAGEDOWN)); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SECONDSCROLL_PAGEUP)); + OutputString(15, x, y, ": Sort by ("); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::CHANGETAB)); + OutputString(15, x, y, ") "); switch (altsort) { case ALTSORT_NAME: - OutputString(15, x, gps->dimy - 2, "Name"); + OutputString(15, x, y, "Name"); break; case ALTSORT_PROFESSION: - OutputString(15, x, gps->dimy - 2, "Profession"); + OutputString(15, x, y, "Profession"); break; case ALTSORT_HAPPINESS: - OutputString(15, x, gps->dimy - 2, "Happiness"); + OutputString(15, x, y, "Happiness"); break; case ALTSORT_ARRIVAL: - OutputString(15, x, gps->dimy - 2, "Arrival"); + OutputString(15, x, y, "Arrival"); break; default: - OutputString(15, x, gps->dimy - 2, "Unknown"); + OutputString(15, x, y, "Unknown"); break; } } @@ -1193,9 +1196,10 @@ struct unitlist_hook : df::viewscreen_unitlistst if (units[page].size()) { - int x = 2; - OutputString(12, x, gps->dimy - 2, Screen::getKeyDisplay(interface_key::UNITVIEW_PRF_PROF)); - OutputString(15, x, gps->dimy - 2, ": Manage labors (DFHack)"); + auto dim = Screen::getWindowSize(); + int x = 2, y = dim.y - 2; + OutputString(12, x, y, Screen::getKeyDisplay(interface_key::UNITVIEW_PRF_PROF)); + OutputString(15, x, y, ": Manage labors (DFHack)"); } } }; diff --git a/plugins/search.cpp b/plugins/search.cpp index cc3f29c12..742fa9277 100644 --- a/plugins/search.cpp +++ b/plugins/search.cpp @@ -329,8 +329,9 @@ protected: // Display hotkey message void print_search_option(int x, int y = -1) const { + auto dim = Screen::getWindowSize(); if (y == -1) - y = gps->dimy - 2; + y = dim.y - 2; OutputString((entry_mode) ? 4 : 12, x, y, string(1, select_key)); OutputString((entry_mode) ? 10 : 15, x, y, ": Search"); @@ -413,8 +414,9 @@ public: print_search_option(2); else { - int x = 2; - OutputString(15, x, gps->dimy - 2, "Tab to enable Search"); + auto dim = Screen::getWindowSize(); + int x = 2, y = dim.y - 2; + OutputString(15, x, y, "Tab to enable Search"); } } From 139fd07df3e738fec33842d645fb1ac947679e61 Mon Sep 17 00:00:00 2001 From: Quietust Date: Fri, 23 Nov 2012 19:23:06 -0600 Subject: [PATCH 12/35] missed a spot --- plugins/manipulator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 59b257979..e8a91fdb6 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -1120,10 +1120,10 @@ void viewscreen_unitlaborsst::render() } int x = 2, y = dim.y - 3; - OutputString(10, x, dim.y - 3, Screen::getKeyDisplay(interface_key::SELECT)); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SELECT)); OutputString(canToggle ? 15 : 8, x, y, ": Toggle labor, "); - OutputString(10, x, dim.y - 3, Screen::getKeyDisplay(interface_key::SELECT_ALL)); + OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SELECT_ALL)); OutputString(canToggle ? 15 : 8, x, y, ": Toggle Group, "); OutputString(10, x, y, Screen::getKeyDisplay(interface_key::UNITJOB_VIEW)); From 8429f651766566f697f36347faba23a98d987f72 Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 22 Nov 2012 16:56:22 +0100 Subject: [PATCH 13/35] add scripts/stripcaged.rb and documentation --- NEWS | 1 + Readme.rst | 45 ++++++++++ scripts/stripcaged.rb | 194 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 scripts/stripcaged.rb diff --git a/NEWS b/NEWS index 463ebb47a..65c647337 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,7 @@ DFHack future - dfusion: misc scripts with a text based menu. - embark: lets you embark anywhere. - lever: list and pull fort levers from the dfhack console. + - stripcaged: mark items inside cages for dumping, eg caged goblin weapons. New GUI scripts: - gui/guide-path: displays the cached path for minecart Guide orders. - gui/workshop-job: displays inputs of a workshop job and allows tweaking them. diff --git a/Readme.rst b/Readme.rst index e6554cac0..3434a240d 100644 --- a/Readme.rst +++ b/Readme.rst @@ -144,6 +144,16 @@ system console: The patches are expected to be encoded in text format used by IDA. + +Live patching +------------- + +As an alternative, you can use the ``binpatch`` dfhack command to apply/remove +patches live in memory during a DF session. + +In this case, updating symbols.xml is not necessary. + + ============================= Something doesn't work, help! ============================= @@ -1956,6 +1966,41 @@ embark ====== Allows to embark anywhere. Currently windows only. +lever +===== +Allow manipulation of in-game levers from the dfhack console. + +Can list levers, including state and links, with:: + + lever list + +To queue a job so that a dwarf will pull the lever 42, use ``lever pull 42``. +This is the same as 'q'uerying the building and queue a 'P'ull request. + +To magically toggle the lever immediately, use:: + + lever pull 42 --now + +stripcaged +========== +For dumping items inside cages. Will mark selected items for dumping, then +a dwarf may come and actually dump it. See also ``autodump``. + +With the ``items`` argument, only dumps items laying in the cage, excluding +stuff worn by caged creatures. ``weapons`` will dump worn weapons, ``armor`` +will dump everything worn by caged creatures (including armor and clothing), +and ``all`` will dump everything, on a creature or not. + +``stripcaged list`` will display on the dfhack console the list of all cages +and their item content. + +Without further arguments, all commands work on all cages and animal traps on +the map. With the ``here`` argument, considers only the in-game selected cage +(or the cage under the game cursor). To target only specific cages, you can +alternatively pass cage IDs as arguments:: + + stripcaged weapons 25321 34228 + ======================= In-game interface tools ======================= diff --git a/scripts/stripcaged.rb b/scripts/stripcaged.rb new file mode 100644 index 000000000..fa9c49552 --- /dev/null +++ b/scripts/stripcaged.rb @@ -0,0 +1,194 @@ +# mark stuff inside of cages for dumping. + +def plural(nr, name) + # '1 cage' / '4 cages' + "#{nr} #{name}#{'s' if nr > 1}" +end + +def cage_dump_items(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsItemst) + next if ref.item_tg.flags.dump + count += 1 + ref.item_tg.flags.dump = true + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_armor(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) + ref.unit_tg.inventory.each { |it| + next if it.mode != :Worn + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'armor piece')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_weapons(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + next unless ref.kind_of?(DFHack::GeneralRefContainsUnitst) + ref.unit_tg.inventory.each { |it| + next if it.mode != :Weapon + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'weapon')} in #{plural(count_cage, 'cage')}" +end + +def cage_dump_all(list) + count = 0 + count_cage = 0 + list.each { |cage| + pre_count = count + cage.general_refs.each { |ref| + case ref + when DFHack::GeneralRefContainsItemst + next if ref.item_tg.flags.dump + count += 1 + ref.item_tg.flags.dump = true + when DFHack::GeneralRefContainsUnitst + ref.unit_tg.inventory.each { |it| + next if it.item.flags.dump + count += 1 + it.item.flags.dump = true + } + end + } + count_cage += 1 if pre_count != count + } + + puts "Dumped #{plural(count, 'item')} in #{plural(count_cage, 'cage')}" +end + + +def cage_dump_list(list) + count_total = Hash.new(0) + list.each { |cage| + count = Hash.new(0) + + cage.general_refs.each { |ref| + case ref + when DFHack::GeneralRefContainsItemst + count[ref.item_tg._rtti_classname] += 1 + when DFHack::GeneralRefContainsUnitst + ref.unit_tg.inventory.each { |it| + count[it.item._rtti_classname] += 1 + } + # TODO vermin ? + else + puts "unhandled ref #{ref.inspect}" if $DEBUG + end + } + + type = case cage + when DFHack::ItemCagest; 'Cage' + when DFHack::ItemAnimaltrapst; 'Animal trap' + else cage._rtti_classname + end + + puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + + count.each { |k, v| count_total[k] += v } + } + + if list.length > 2 + puts '', "Total: ", count_total.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + end +end + + +# handle magic script arguments +here_only = $script_args.delete 'here' +if here_only + it = df.item_find + list = [it] + if not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) + list = df.world.items.other[:ANY_CAGE_OR_TRAP].find_all { |i| df.at_cursor?(i) } + end + puts 'Please select a cage' if list.empty? + +elsif ids = $script_args.find_all { |arg| arg =~ /^\d+$/ } and ids.first + list = [] + ids.each { |id| + $script_args.delete id + if not it = df.item_find(id.to_i) + puts "Invalid item id #{id}" + elsif not it.kind_of?(DFHack::ItemCagest) and not it.kind_of?(DFHack::ItemAnimaltrapst) + puts "Item ##{id} is not a cage" + list << it + else + list << it + end + } + puts 'Please use a valid cage id' if list.empty? + +else + list = df.world.items.other[:ANY_CAGE_OR_TRAP] +end + + +# act +case $script_args[0] +when 'items' + cage_dump_items(list) if not list.empty? +when 'armor' + cage_dump_armor(list) if not list.empty? +when 'weapons' + cage_dump_weapons(list) if not list.empty? +when 'all' + cage_dump_all(list) if not list.empty? + +when 'list' + cage_dump_list(list) if not list.empty? + +else + puts < Date: Thu, 22 Nov 2012 17:42:10 +0100 Subject: [PATCH 14/35] scripts/lever: show pending jobs --- scripts/lever.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/lever.rb b/scripts/lever.rb index 2c7735146..59196f7d2 100644 --- a/scripts/lever.rb +++ b/scripts/lever.rb @@ -10,6 +10,8 @@ def lever_pull_job(bld) job.general_refs << ref bld.jobs << job df.job_link job + + puts lever_descr(bld) end def lever_pull_cheat(bld) @@ -31,6 +33,14 @@ def lever_descr(bld, idx=nil) descr = '' descr << "#{idx}: " if idx descr << "lever ##{bld.id} @[#{bld.centerx}, #{bld.centery}, #{bld.z}] #{bld.state == 0 ? '\\' : '/'}" + bld.jobs.each { |j| + if j.job_type == :PullLever + flags = '' + flags << ', repeat' if j.flags.repeat + flags << ', suspended' if j.flags.suspend + descr << " (pull order#{flags})" + end + } bld.linked_mechanisms.map { |i| i.general_refs.grep(DFHack::GeneralRefBuildingHolderst) From cb06c896984735c59a72570dd50f5dfc62bc40ab Mon Sep 17 00:00:00 2001 From: jj Date: Fri, 23 Nov 2012 17:20:16 +0100 Subject: [PATCH 15/35] stripcaged: dont list empty cages individually --- scripts/stripcaged.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/stripcaged.rb b/scripts/stripcaged.rb index fa9c49552..07694f711 100644 --- a/scripts/stripcaged.rb +++ b/scripts/stripcaged.rb @@ -90,6 +90,7 @@ end def cage_dump_list(list) count_total = Hash.new(0) + empty_cages = 0 list.each { |cage| count = Hash.new(0) @@ -113,13 +114,18 @@ def cage_dump_list(list) else cage._rtti_classname end - puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + if count.empty? + empty_cages += 1 + else + puts "#{type} ##{cage.id}: ", count.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + end count.each { |k, v| count_total[k] += v } } if list.length > 2 puts '', "Total: ", count_total.sort_by { |k, v| v }.map { |k, v| " #{v} #{k}" } + puts "with #{plural(empty_cages, 'empty cage')}" end end From e73274d281e4f7f8b476a64a4854400dbb40c791 Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 24 Nov 2012 16:05:03 +0100 Subject: [PATCH 16/35] ruby: add description field to onupdate_register --- plugins/ruby/README | 4 ++-- plugins/ruby/ruby.rb | 38 ++++++++++++++++++++------------------ scripts/autofarm.rb | 16 ++++++++-------- scripts/autounsuspend.rb | 6 +++--- scripts/magmasource.rb | 2 +- scripts/slayrace.rb | 2 +- scripts/superdwarf.rb | 4 ++-- 7 files changed, 37 insertions(+), 35 deletions(-) diff --git a/plugins/ruby/README b/plugins/ruby/README index 9246fec88..d35c34bbe 100644 --- a/plugins/ruby/README +++ b/plugins/ruby/README @@ -125,9 +125,9 @@ DFHack callbacks The plugin interfaces with dfhack 'onupdate' hook. To register ruby code to be run every graphic frame, use: - handle = df.onupdate_register { puts 'i love flooding the console' } + handle = df.onupdate_register('log') { puts 'i love flooding the console' } You can also rate-limit when your callback is called to a number of game ticks: - handle = df.onupdate_register(10) { puts '10 more in-game ticks elapsed' } + handle = df.onupdate_register('myname', 10) { puts '10 more in-game ticks elapsed' } In this case, the callback is called immediately, and then every X in-game ticks (advances only when the game is unpaused). To stop being called, use: diff --git a/plugins/ruby/ruby.rb b/plugins/ruby/ruby.rb index ab095e8d8..4fcb5543a 100644 --- a/plugins/ruby/ruby.rb +++ b/plugins/ruby/ruby.rb @@ -24,8 +24,9 @@ end module DFHack class OnupdateCallback - attr_accessor :callback, :timelimit, :minyear, :minyeartick - def initialize(cb, tl, initdelay=0) + attr_accessor :callback, :timelimit, :minyear, :minyeartick, :description + def initialize(descr, cb, tl, initdelay=0) + @description = descr @callback = cb @ticklimit = tl @minyear = (tl ? df.cur_year : 0) @@ -34,22 +35,21 @@ module DFHack # run callback if timedout def check_run(year, yeartick, yearlen) - if !@ticklimit - @callback.call - else - if year > @minyear or (year == @minyear and yeartick >= @minyeartick) - @minyear = year - @minyeartick = yeartick + @ticklimit - if @minyeartick > yearlen - @minyear += 1 - @minyeartick -= yearlen - end - @callback.call + if @ticklimit + return unless year > @minyear or (year == @minyear and yeartick >= @minyeartick) + @minyear = year + @minyeartick = yeartick + @ticklimit + if @minyeartick > yearlen + @minyear += 1 + @minyeartick -= yearlen end end + # t0 = Time.now + @callback.call + # dt = Time.now - t0 ; puts "rb cb #@description took #{'%.02f' % dt}s" if dt > 0.1 rescue df.onupdate_unregister self - puts_err "onupdate cb #$!", $!.backtrace + puts_err "onupdate #@description unregistered: #$!", $!.backtrace end def <=>(o) @@ -61,10 +61,11 @@ module DFHack attr_accessor :onupdate_list, :onstatechange_list # register a callback to be called every gframe or more - # ex: DFHack.onupdate_register { DFHack.world.units[0].counters.job_counter = 0 } - def onupdate_register(ticklimit=nil, initialtickdelay=0, &b) + # ex: DFHack.onupdate_register('fastdwarf') { DFHack.world.units[0].counters.job_counter = 0 } + def onupdate_register(descr, ticklimit=nil, initialtickdelay=0, &b) + raise ArgumentError, 'need a description as 1st arg' unless descr.kind_of?(::String) @onupdate_list ||= [] - @onupdate_list << OnupdateCallback.new(b, ticklimit, initialtickdelay) + @onupdate_list << OnupdateCallback.new(descr, b, ticklimit, initialtickdelay) DFHack.onupdate_active = true if onext = @onupdate_list.sort.first DFHack.onupdate_minyear = onext.minyear @@ -73,8 +74,9 @@ module DFHack @onupdate_list.last end - # delete the callback for onupdate ; use the value returned by onupdate_register + # delete the callback for onupdate ; use the value returned by onupdate_register or the description def onupdate_unregister(b) + b = @onupdate_list.find { |bb| bb.description == b } if b.kind_of?(String) @onupdate_list.delete b if @onupdate_list.empty? DFHack.onupdate_active = false diff --git a/scripts/autofarm.rb b/scripts/autofarm.rb index 098466745..c89cb9ff4 100644 --- a/scripts/autofarm.rb +++ b/scripts/autofarm.rb @@ -5,7 +5,7 @@ class AutoFarm @lastcounts = Hash.new(0) end - def setthreshold (id, v) + def setthreshold(id, v) if df.world.raws.plants.all.find { |r| r.id == id } @thresholds[id] = v.to_i else @@ -13,11 +13,11 @@ class AutoFarm end end - def setdefault (v) + def setdefault(v) @thresholds.default = v.to_i end - def is_plantable (plant) + def is_plantable(plant) season = df.cur_season harvest = df.cur_season_tick + plant.growdur * 10 will_finish = harvest < 10080 @@ -40,7 +40,7 @@ class AutoFarm return plantable end - def set_farms ( plants, farms) + def set_farms( plants, farms) return if farms.length == 0 if plants.length == 0 plants = [-1] @@ -66,7 +66,7 @@ class AutoFarm if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect && !i.flags.hostile && !i.flags.on_fire && !i.flags.rotten && !i.flags.trader && !i.flags.in_building && !i.flags.construction && - !i.flags.artifact1 && plantable.has_key? (i.mat_index)) + !i.flags.artifact1 && plantable.has_key?(i.mat_index)) counts[i.mat_index] = counts[i.mat_index] + i.stack_size end } @@ -95,13 +95,13 @@ class AutoFarm end } - set_farms (plants_s, farms_s) - set_farms (plants_u, farms_u) + set_farms(plants_s, farms_s) + set_farms(plants_u, farms_u) end def start - @onupdate = df.onupdate_register (100) { process } + @onupdate = df.onupdate_register('autofarm', 100) { process } @running = true end diff --git a/scripts/autounsuspend.rb b/scripts/autounsuspend.rb index 45dd8df4d..c7fe20748 100644 --- a/scripts/autounsuspend.rb +++ b/scripts/autounsuspend.rb @@ -26,7 +26,7 @@ class AutoUnsuspend end def start - @onupdate = df.onupdate_register (5) { process } + @onupdate = df.onupdate_register('autounsuspend', 5) { process } @running = true end @@ -36,7 +36,7 @@ class AutoUnsuspend end def status - stat = @running ? "Running." : "Loaded." + @running ? 'Running.' : 'Stopped.' end end @@ -53,6 +53,6 @@ else if $AutoUnsuspend puts $AutoUnsuspend.status else - puts "AI not started" + puts 'Not loaded.' end end diff --git a/scripts/magmasource.rb b/scripts/magmasource.rb index e97080834..c20199c2a 100644 --- a/scripts/magmasource.rb +++ b/scripts/magmasource.rb @@ -4,7 +4,7 @@ $magma_sources ||= [] case $script_args[0] when 'here' - $magma_onupdate ||= df.onupdate_register(12) { + $magma_onupdate ||= df.onupdate_register('magmasource', 12) { # called every 12 game ticks (100x a dwarf day) if $magma_sources.empty? df.onupdate_unregister($magma_onupdate) diff --git a/scripts/slayrace.rb b/scripts/slayrace.rb index 749d0189b..ca50020f7 100644 --- a/scripts/slayrace.rb +++ b/scripts/slayrace.rb @@ -21,7 +21,7 @@ slayit = lambda { |u| else # it's getting hot around here # !!WARNING!! do not call on a magma-safe creature - ouh = df.onupdate_register(1) { + ouh = df.onupdate_register("slayrace ensure #{u.id}", 1) { if u.flags1.dead df.onupdate_unregister(ouh) else diff --git a/scripts/superdwarf.rb b/scripts/superdwarf.rb index 6277db97f..eac9802fa 100644 --- a/scripts/superdwarf.rb +++ b/scripts/superdwarf.rb @@ -8,12 +8,12 @@ when 'add' if u = df.unit_find $superdwarf_ids |= [u.id] - if df.gamemode == :ADVENTURE + if df.gamemode == :ADVENTURE and not df.respond_to?(:cur_year_tick_advmode) onupdate_delay = nil else onupdate_delay = 1 end - $superdwarf_onupdate ||= df.onupdate_register(onupdate_delay) { + $superdwarf_onupdate ||= df.onupdate_register('superdwarf', onupdate_delay) { if $superdwarf_ids.empty? df.onupdate_unregister($superdwarf_onupdate) $superdwarf_onupdate = nil From 4dfe46e26f139167cc51ec689c19b3ba08747c0d Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 24 Nov 2012 16:52:21 +0100 Subject: [PATCH 17/35] manipulator: fix column width calculations for 80x25 window --- plugins/manipulator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index e8a91fdb6..57c9390bb 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -469,10 +469,10 @@ void viewscreen_unitlaborsst::calcSize() int col_maxwidth[DISP_COLUMN_MAX]; col_minwidth[DISP_COLUMN_HAPPINESS] = 4; col_maxwidth[DISP_COLUMN_HAPPINESS] = 4; - col_minwidth[DISP_COLUMN_NAME] = 0; - col_maxwidth[DISP_COLUMN_NAME] = 0; - col_minwidth[DISP_COLUMN_PROFESSION] = 0; - col_maxwidth[DISP_COLUMN_PROFESSION] = 0; + col_minwidth[DISP_COLUMN_NAME] = 15; + col_maxwidth[DISP_COLUMN_NAME] = 15; // adjusted in the loop below + col_minwidth[DISP_COLUMN_PROFESSION] = 15; + col_maxwidth[DISP_COLUMN_PROFESSION] = 15; // adjusted in the loop below col_minwidth[DISP_COLUMN_LABORS] = num_columns*3/5; // 60% col_maxwidth[DISP_COLUMN_LABORS] = NUM_COLUMNS; From cdc44b74f2d8d353d0beab7e73bfa8bbf916151c Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 24 Nov 2012 10:36:32 -0600 Subject: [PATCH 18/35] Fix possible crash when using shift+enter on cells that don't have labors --- plugins/manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 57c9390bb..d8b44f657 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -842,7 +842,7 @@ void viewscreen_unitlaborsst::feed(set *events) { df::unit *unit = cur->unit; const SkillColumn &col = columns[input_column]; - bool newstatus = !unit->status.labors[col.labor]; + bool newstatus = (col.labor == unit_labor::NONE) ? true : !unit->status.labors[col.labor]; for (int i = 0; i < NUM_COLUMNS; i++) { if (columns[i].group != col.group) From c58f30ba0095248512c3b1320de6869620794377 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 24 Nov 2012 10:37:22 -0600 Subject: [PATCH 19/35] Use teal background instead of red for no-labor cells --- plugins/manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index d8b44f657..3e1a414ff 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -1060,7 +1060,7 @@ void viewscreen_unitlaborsst::render() } } else - bg = 4; + bg = 3; Screen::paintTile(Screen::Pen(c, fg, bg), col_offsets[DISP_COLUMN_LABORS] + col, 4 + row); } } From e9141f34f6dd9354a4eed0498aa72ff944cc1189 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 24 Nov 2012 11:13:54 -0600 Subject: [PATCH 20/35] Adjust minimum widths so they actually work at 80x25 without glitching out --- plugins/manipulator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 3e1a414ff..88dc61726 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -469,10 +469,10 @@ void viewscreen_unitlaborsst::calcSize() int col_maxwidth[DISP_COLUMN_MAX]; col_minwidth[DISP_COLUMN_HAPPINESS] = 4; col_maxwidth[DISP_COLUMN_HAPPINESS] = 4; - col_minwidth[DISP_COLUMN_NAME] = 15; - col_maxwidth[DISP_COLUMN_NAME] = 15; // adjusted in the loop below - col_minwidth[DISP_COLUMN_PROFESSION] = 15; - col_maxwidth[DISP_COLUMN_PROFESSION] = 15; // adjusted in the loop below + col_minwidth[DISP_COLUMN_NAME] = 16; + col_maxwidth[DISP_COLUMN_NAME] = 16; // adjusted in the loop below + col_minwidth[DISP_COLUMN_PROFESSION] = 10; + col_maxwidth[DISP_COLUMN_PROFESSION] = 10; // adjusted in the loop below col_minwidth[DISP_COLUMN_LABORS] = num_columns*3/5; // 60% col_maxwidth[DISP_COLUMN_LABORS] = NUM_COLUMNS; From f091284a75b52b84dbe602d85345bae9bcfc2422 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 25 Nov 2012 17:29:03 +0100 Subject: [PATCH 21/35] ruby: avoid crash on ArgumentError in onupdate --- plugins/ruby/ruby.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ruby/ruby.rb b/plugins/ruby/ruby.rb index 4fcb5543a..b7f7590e9 100644 --- a/plugins/ruby/ruby.rb +++ b/plugins/ruby/ruby.rb @@ -47,7 +47,7 @@ module DFHack # t0 = Time.now @callback.call # dt = Time.now - t0 ; puts "rb cb #@description took #{'%.02f' % dt}s" if dt > 0.1 - rescue + rescue Exception df.onupdate_unregister self puts_err "onupdate #@description unregistered: #$!", $!.backtrace end From 76bb5f0196e5f57be0e7c3bdd4947c8bd6416fc3 Mon Sep 17 00:00:00 2001 From: jj Date: Mon, 26 Nov 2012 20:09:56 +0100 Subject: [PATCH 22/35] ruby: items in containers are free --- plugins/ruby/item.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ruby/item.rb b/plugins/ruby/item.rb index 469ec7449..0d65a707b 100644 --- a/plugins/ruby/item.rb +++ b/plugins/ruby/item.rb @@ -56,7 +56,7 @@ module DFHack def item_isfree(i) !i.flags.trader and !i.flags.in_job and - !i.flags.in_inventory and + (!i.flags.in_inventory or i.general_refs.grep(GeneralRefContainedInItemst).first) and !i.flags.removed and !i.flags.in_building and !i.flags.owned and From 536fd5546a8420340d0f6ca2fc8e5133bbda447b Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 27 Nov 2012 13:56:02 +0400 Subject: [PATCH 23/35] Update manipulator screenshots. --- Readme.html | 639 +++++++++++++++++++++------------------- Readme.rst | 8 +- images/manipulator.png | Bin 7373 -> 9024 bytes images/manipulator2.png | Bin 0 -> 8840 bytes 4 files changed, 348 insertions(+), 299 deletions(-) create mode 100644 images/manipulator2.png diff --git a/Readme.html b/Readme.html index 5b231b429..cdc4dd631 100644 --- a/Readme.html +++ b/Readme.html @@ -342,200 +342,205 @@ access DF memory and allow for easier development of new tools.

  • Using DFHack
  • -

    Something doesn't work, help!

    +

    Something doesn't work, help!

    First, don't panic :) Second, dfhack keeps a few log files in DF's folder - stderr.log and stdout.log. You can look at those and possibly find out what's happening. @@ -661,13 +672,13 @@ the issues tracker on github, contact me ( -

    The init file

    +

    The init file

    If your DF folder contains a file named dfhack.init, its contents will be run every time you start DF. This allows setting up keybindings. An example file is provided as dfhack.init-example - you can tweak it and rename to dfhack.init if you want to use this functionality.

    -

    Setting keybindings

    +

    Setting keybindings

    To set keybindings, use the built-in keybinding command. Like any other command it can be used at any time from the console, but it is also meaningful in the DFHack init file.

    @@ -712,7 +723,7 @@ for context foo/bar/baz, possible matches are
    -

    Commands

    +

    Commands

    DFHack command syntax consists of a command name, followed by arguments separated by whitespace. To include whitespace in an argument, quote it in double quotes. To include a double quote character, use \" inside double quotes.

    @@ -734,13 +745,13 @@ The following two command lines are exactly equivalent:

    to retrieve further help without having to look at this document. Alternatively, some accept a 'help'/'?' option on their command line.

    -

    Game progress

    +

    Game progress

    -

    die

    +

    die

    Instantly kills DF without saving.

    -

    forcepause

    +

    forcepause

    Forces DF to pause. This is useful when your FPS drops below 1 and you lose control of the game.

    @@ -751,12 +762,12 @@ control of the game.

    -

    nopause

    +

    nopause

    Disables pausing (both manual and automatic) with the exception of pause forced by 'reveal hell'. This is nice for digging under rivers.

    -

    fastdwarf

    +

    fastdwarf

    Controls speedydwarf and teledwarf. Speedydwarf makes dwarves move quickly and perform tasks quickly. Teledwarf makes dwarves move instantaneously, but do jobs at the same speed.

      @@ -773,29 +784,29 @@ that implements an even more aggressive version of speedydwarf.
    -

    Game interface

    +

    Game interface

    -

    follow

    +

    follow

    Makes the game view follow the currently highlighted unit after you exit from current menu/cursor mode. Handy for watching dwarves running around. Deactivated by moving the view manually.

    -

    tidlers

    +

    tidlers

    Toggle between all possible positions where the idlers count can be placed.

    -

    twaterlvl

    +

    twaterlvl

    Toggle between displaying/not displaying liquid depth as numbers.

    -

    copystock

    +

    copystock

    Copies the parameters of the currently highlighted stockpile to the custom stockpile settings and switches to custom stockpile placement mode, effectively allowing you to copy/paste stockpiles easily.

    -

    rename

    +

    rename

    Allows renaming various things.

    Options:

    @@ -829,9 +840,9 @@ siege engine or an activity zone.
    -

    Adventure mode

    +

    Adventure mode

    -

    adv-bodyswap

    +

    adv-bodyswap

    This allows taking control over your followers and other creatures in adventure mode. For example, you can make them pick up new arms and armor and equip them properly.

    @@ -844,7 +855,7 @@ properly.

    -

    advtools

    +

    advtools

    A package of different adventure mode tools (currently just one)

    Usage:

    @@ -867,9 +878,9 @@ on item type and being in shop.
    -

    Map modification

    +

    Map modification

    -

    changelayer

    +

    changelayer

    Changes material of the geology layer under cursor to the specified inorganic RAW material. Can have impact on all surrounding regions, not only your embark! By default changing stone to soil and vice versa is not allowed. By default @@ -944,7 +955,7 @@ You did save your game, right?

    -

    changevein

    +

    changevein

    Changes material of the vein under cursor to the specified inorganic RAW material. Only affects tiles within the current 16x16 block - for veins and large clusters, you will need to use this command multiple times.

    @@ -957,7 +968,7 @@ large clusters, you will need to use this command multiple times.

    -

    changeitem

    +

    changeitem

    Allows changing item material and base quality. By default the item currently selected in the UI will be changed (you can select items in the 'k' list or inside containers/inventory). By default change is only allowed if materials @@ -997,7 +1008,7 @@ crafters/haulers.

    -

    colonies

    +

    colonies

    Allows listing all the vermin colonies on the map and optionally turning them into honey bee colonies.

    Options:

    @@ -1012,12 +1023,12 @@ crafters/haulers.

    -

    deramp (by zilpin)

    +

    deramp (by zilpin)

    Removes all ramps designated for removal from the map. This is useful for replicating the old channel digging designation. It also removes any and all 'down ramps' that can remain after a cave-in (you don't have to designate anything for that to happen).

    -

    feature

    +

    feature

    Enables management of map features.

    • Discovering a magma feature (magma pool, volcano, magma sea, or curious @@ -1042,7 +1053,7 @@ that cavern to grow within your fortress.
    -

    liquids

    +

    liquids

    Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command @@ -1055,13 +1066,13 @@ temperatures (creating heat traps). You've been warned.

    -

    liquids-here

    +

    liquids-here

    Run the liquid spawner with the current/last settings made in liquids (if no settings in liquids were made it paints a point of 7/7 magma by default).

    Intended to be used as keybinding. Requires an active in-game cursor.

    -

    tiletypes

    +

    tiletypes

    Can be used for painting map tiles and is an interactive command, much like liquids.

    The tool works with two set of options and a brush. The brush determines which @@ -1122,27 +1133,27 @@ up.

    For more details, see the 'help' command while using this.

    -

    tiletypes-commands

    +

    tiletypes-commands

    Runs tiletypes commands, separated by ;. This makes it possible to change tiletypes modes from a hotkey.

    -

    tiletypes-here

    +

    tiletypes-here

    Apply the current tiletypes options at the in-game cursor position, including the brush. Can be used from a hotkey.

    -

    tiletypes-here-point

    +

    tiletypes-here-point

    Apply the current tiletypes options at the in-game cursor position to a single tile. Can be used from a hotkey.

    -

    tubefill

    +

    tubefill

    Fills all the adamantine veins again. Veins that were empty will be filled in too, but might still trigger a demon invasion (this is a known bug).

    -

    extirpate

    +

    extirpate

    A tool for getting rid of trees and shrubs. By default, it only kills a tree/shrub under the cursor. The plants are turned into ashes instantly.

    Options:

    @@ -1162,20 +1173,20 @@ a tree/shrub under the cursor. The plants are turned into ashes instantly.

    -

    grow

    +

    grow

    Makes all saplings present on the map grow into trees (almost) instantly.

    -

    immolate

    +

    immolate

    Very similar to extirpate, but additionally sets the plants on fire. The fires can and will spread ;)

    -

    regrass

    +

    regrass

    Regrows grass. Not much to it ;)

    -

    weather

    +

    weather

    Prints the current weather map by default.

    Also lets you change the current weather to 'clear sky', 'rainy' or 'snowing'.

    Options:

    @@ -1196,9 +1207,9 @@ can and will spread ;)

    -

    Map inspection

    +

    Map inspection

    -

    cursecheck

    +

    cursecheck

    Checks a single map tile or the whole map/world for cursed creatures (ghosts, vampires, necromancers, werebeasts, zombies).

    With an active in-game cursor only the selected tile will be observed. @@ -1253,17 +1264,17 @@ of curses, for example.

    -

    flows

    +

    flows

    A tool for checking how many tiles contain flowing liquids. If you suspect that your magma sea leaks into HFS, you can use this tool to be sure without revealing the map.

    -

    probe

    +

    probe

    Can be used to determine tile properties like temperature.

    -

    prospect

    +

    prospect

    Prints a big list of all the present minerals and plants. By default, only the visible part of the map is scanned.

    Options:

    @@ -1282,7 +1293,7 @@ the visible part of the map is scanned.

    -

    Pre-embark estimate

    +

    Pre-embark estimate

    If prospect is called during the embark selection screen, it displays an estimate of layer stone availability.

    @@ -1307,7 +1318,7 @@ that is actually present.

    -

    reveal

    +

    reveal

    This reveals the map. By default, HFS will remain hidden so that the demons don't spawn. You can use 'reveal hell' to reveal everything. With hell revealed, you won't be able to unpause until you hide the map again. If you really want @@ -1316,34 +1327,34 @@ to unpause with hell revealed, use 'reveal demons'.

    you move. When you use it this way, you don't need to run 'unreveal'.

    -

    unreveal

    +

    unreveal

    Reverts the effects of 'reveal'.

    -

    revtoggle

    +

    revtoggle

    Switches between 'reveal' and 'unreveal'.

    -

    revflood

    +

    revflood

    This command will hide the whole map and then reveal all the tiles that have a path to the in-game cursor.

    -

    revforget

    +

    revforget

    When you use reveal, it saves information about what was/wasn't visible before revealing everything. Unreveal uses this information to hide things again. This command throws away the information. For example, use in cases where you abandoned with the fort revealed and no longer want the data.

    -

    showmood

    +

    showmood

    Shows all items needed for the currently active strange mood.

    -

    Designations

    +

    Designations

    -

    burrow

    +

    burrow

    Miscellaneous burrow control. Allows manipulating burrows and automated burrow expansion while digging.

    Options:

    @@ -1391,17 +1402,17 @@ Digging 1-wide corridors with the miner inside the burrow is SLOW.
    -

    digv

    +

    digv

    Designates a whole vein for digging. Requires an active in-game cursor placed over a vein tile. With the 'x' option, it will traverse z-levels (putting stairs between the same-material tiles).

    -

    digvx

    +

    digvx

    A permanent alias for 'digv x'.

    -

    digl

    +

    digl

    Designates layer stone for digging. Requires an active in-game cursor placed over a layer stone tile. With the 'x' option, it will traverse z-levels (putting stairs between the same-material tiles). With the 'undo' option it @@ -1409,11 +1420,11 @@ will remove the dig designation instead (if you realize that digging out a 50 z-level deep layer was not such a good idea after all).

    -

    diglx

    +

    diglx

    A permanent alias for 'digl x'.

    -

    digexp

    +

    digexp

    This command can be used for exploratory mining.

    See: http://df.magmawiki.com/index.php/DF2010:Exploratory_mining

    There are two variables that can be set: pattern and filter.

    @@ -1476,7 +1487,7 @@ z-level deep layer was not such a good idea after all).

    -

    digcircle

    +

    digcircle

    A command for easy designation of filled and hollow circles. It has several types of options.

    Shape:

    @@ -1539,7 +1550,7 @@ repeats with the last selected parameters.

    -

    digtype

    +

    digtype

    For every tile on the map of the same vein type as the selected tile, this command designates it to have the same designation as the selected tile. If the selected tile has no designation, they will be dig designated. If an argument is given, the designation of the selected tile is ignored, and all appropriate tiles are set to the specified designation.

    Options:

    @@ -1567,7 +1578,7 @@ If an argument is given, the designation of the selected tile is ignored, and al
    -

    filltraffic

    +

    filltraffic

    Set traffic designations using flood-fill starting at the cursor.

    Traffic Type Codes:

    @@ -1606,7 +1617,7 @@ If an argument is given, the designation of the selected tile is ignored, and al 'filltraffic H' - When used in a room with doors, it will set traffic to HIGH in just that room.
    -

    alltraffic

    +

    alltraffic

    Set traffic designations for every single tile of the map (useful for resetting traffic designations).

    Traffic Type Codes:

    @@ -1630,7 +1641,7 @@ If an argument is given, the designation of the selected tile is ignored, and al 'alltraffic N' - Set traffic to 'normal' for all tiles.
    -

    getplants

    +

    getplants

    This tool allows plant gathering and tree cutting by RAW ID. Specify the types of trees to cut down and/or shrubs to gather by their plant names, separated by spaces.

    @@ -1657,9 +1668,9 @@ all valid plant IDs will be listed.

    -

    Cleanup and garbage disposal

    +

    Cleanup and garbage disposal

    -

    clean

    +

    clean

    Cleans all the splatter that get scattered all over the map, items and creatures. In an old fortress, this can significantly reduce FPS lag. It can also spoil your !!FUN!!, so think before you use it.

    @@ -1693,12 +1704,12 @@ also spoil your !!FUN!!, so think before you use it.

    -

    spotclean

    +

    spotclean

    Works like 'clean map snow mud', but only for the tile under the cursor. Ideal if you want to keep that bloody entrance 'clean map' would clean up.

    -

    autodump

    +

    autodump

    This utility lets you quickly move all items designated to be dumped. Items are instantly moved to the cursor position, the dump flag is unset, and the forbid flag is set, as if it had been dumped normally. @@ -1725,17 +1736,17 @@ Be aware that any active dump item tasks still point at the item.

    -

    autodump-destroy-here

    +

    autodump-destroy-here

    Destroy items marked for dumping under cursor. Identical to autodump destroy-here, but intended for use as keybinding.

    -

    autodump-destroy-item

    +

    autodump-destroy-item

    Destroy the selected item. The item may be selected in the 'k' list, or inside a container. If called again before the game is resumed, cancels destroy.

    -

    cleanowned

    +

    cleanowned

    Confiscates items owned by dwarfs. By default, owned food on the floor and rotten items are confistacted and dumped.

    Options:

    @@ -1769,13 +1780,13 @@ worn items with 'X' damage and above.
    -

    Bugfixes

    +

    Bugfixes

    -

    drybuckets

    +

    drybuckets

    This utility removes water from all buckets in your fortress, allowing them to be safely used for making lye.

    -

    fixdiplomats

    +

    fixdiplomats

    Up to version 0.31.12, Elves only sent Diplomats to your fortress to propose tree cutting quotas due to a bug; once that bug was fixed, Elves stopped caring about excess tree cutting. This command adds a Diplomat position to all Elven @@ -1784,19 +1795,19 @@ to violate them and potentially start wars) in case you haven't already modified your raws accordingly.

    -

    fixmerchants

    +

    fixmerchants

    This command adds the Guild Representative position to all Human civilizations, allowing them to make trade agreements (just as they did back in 0.28.181.40d and earlier) in case you haven't already modified your raws accordingly.

    -

    fixveins

    +

    fixveins

    Removes invalid references to mineral inclusions and restores missing ones. Use this if you broke your embark with tools like tiletypes, or if you accidentally placed a construction on top of a valuable mineral floor.

    -

    tweak

    +

    tweak

    Contains various tweaks for minor bugs.

    One-shot subcommands:

    @@ -1902,7 +1913,7 @@ the units spar more.

    -

    fix-armory

    +

    fix-armory

    Enables a fix for storage of squad equipment in barracks.

    Specifically, it prevents your haulers from moving squad equipment to stockpiles, and instead queues jobs to store it on weapon racks, @@ -1956,9 +1967,9 @@ these rules is intended by Toady; the rest are invented by this plugin.

    -

    Mode switch and reclaim

    +

    Mode switch and reclaim

    -

    lair

    +

    lair

    This command allows you to mark the map as 'monster lair', preventing item scatter on abandon. When invoked as 'lair reset', it does the opposite.

    Unlike reveal, this command doesn't save the information about tiles - you @@ -1978,7 +1989,7 @@ won't be able to restore state of real monster lairs using 'lair reset'.

    -

    mode

    +

    mode

    This command lets you see and change the game mode directly. Not all combinations are good for every situation and most of them will produce undesirable results. There are a few good ones though.

    @@ -1998,9 +2009,9 @@ You just created a returnable mountain home and gained an adventurer.

    -

    Visualizer and data export

    +

    Visualizer and data export

    -

    ssense / stonesense

    +

    ssense / stonesense

    An isometric visualizer that runs in a second window. This requires working graphics acceleration and at least a dual core CPU (otherwise it will slow down DF).

    @@ -2013,19 +2024,19 @@ thread: http://df.magmawiki.com/index.php/Utility:Stonesense/Content_repository

    -

    mapexport

    +

    mapexport

    Export the current loaded map as a file. This will be eventually usable with visualizers.

    -

    dwarfexport

    +

    dwarfexport

    Export dwarves to RuneSmith-compatible XML.

    -

    Job management

    +

    Job management

    -

    job

    +

    job

    Command for general job query and manipulation.

    Options:
    @@ -2044,7 +2055,7 @@ in a workshop, or the unit/jobs screen.
    -

    job-material

    +

    job-material

    Alter the material of the selected job.

    Invoked as:

    @@ -2062,7 +2073,7 @@ over the first available choice with the matching material.
     
     
    -

    job-duplicate

    +

    job-duplicate

    Duplicate the selected job in a workshop:
      @@ -2073,7 +2084,7 @@ instantly duplicates the job.
    -

    workflow

    +

    workflow

    Manage control of repeat jobs.

    Usage:

    @@ -2105,7 +2116,7 @@ this list can be copied to a file, and then reloaded using the
    -

    Function

    +

    Function

    When the plugin is enabled, it protects all repeat jobs from removal. If they do disappear due to any cause, they are immediately re-added to their workshop and suspended.

    @@ -2118,7 +2129,7 @@ the frequency of jobs being toggled.

    in the game UI.

    -

    Constraint format

    +

    Constraint format

    The contstraint spec consists of 4 parts, separated with '/' characters:

     ITEM[:SUBTYPE]/[GENERIC_MAT,...]/[SPECIFIC_MAT:...]/[LOCAL,<quality>]
    @@ -2147,7 +2158,7 @@ be used to ignore imported items or items below a certain quality.

    -

    Constraint examples

    +

    Constraint examples

    Keep metal bolts within 900-1000, and wood/bone within 150-200.

     workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 100
    @@ -2196,15 +2207,15 @@ workflow count CRAFTS///LOCAL,EXCEPTIONAL 100 90
     
    -

    Fortress activity management

    +

    Fortress activity management

    -

    seedwatch

    +

    seedwatch

    Tool for turning cooking of seeds and plants on/off depending on how much you have of them.

    See 'seedwatch help' for detailed description.

    -

    zone

    +

    zone

    Helps a bit with managing activity zones (pens, pastures and pits) and cages.

    Options:

    @@ -2303,7 +2314,7 @@ for war/hunt). Negatable.
    -

    Usage with single units

    +

    Usage with single units

    One convenient way to use the zone tool is to bind the command 'zone assign' to a hotkey, maybe also the command 'zone set'. Place the in-game cursor over a pen/pasture or pit, use 'zone set' to mark it. Then you can select units @@ -2312,7 +2323,7 @@ and use 'zone assign' to assign them to their new home. Allows pitting your own dwarves, by the way.

    -

    Usage with filters

    +

    Usage with filters

    All filters can be used together with the 'assign' command.

    Restrictions: It's not possible to assign units who are inside built cages or chained because in most cases that won't be desirable anyways. @@ -2330,14 +2341,14 @@ are not properly added to your own stocks; slaughtering them should work).

    Most filters can be negated (e.g. 'not grazer' -> race is not a grazer).

    -

    Mass-renaming

    +

    Mass-renaming

    Using the 'nick' command you can set the same nickname for multiple units. If used without 'assign', 'all' or 'count' it will rename all units in the current default target zone. Combined with 'assign', 'all' or 'count' (and further optional filters) it will rename units matching the filter conditions.

    -

    Cage zones

    +

    Cage zones

    Using the 'tocages' command you can assign units to a set of cages, for example a room next to your butcher shop(s). They will be spread evenly among available cages to optimize hauling to and butchering from them. For this to work you need @@ -2348,7 +2359,7 @@ would make no sense, but can be used together with 'nick' or 'remnick' and all the usual filters.

    -

    Examples

    +

    Examples

    zone assign all own ALPACA minage 3 maxage 10
    Assign all own alpacas who are between 3 and 10 years old to the selected @@ -2374,7 +2385,7 @@ on the current default zone.
    -

    autonestbox

    +

    autonestbox

    Assigns unpastured female egg-layers to nestbox zones. Requires that you create pen/pasture zones above nestboxes. If the pen is bigger than 1x1 the nestbox must be in the top left corner. Only 1 unit will be assigned per pen, regardless @@ -2403,7 +2414,7 @@ frames between runs.

    -

    autobutcher

    +

    autobutcher

    Assigns lifestock for slaughter once it reaches a specific count. Requires that you add the target race(s) to a watch list. Only tame units will be processed.

    Named units will be completely ignored (to protect specific animals from @@ -2511,7 +2522,7 @@ autobutcher.bat

    -

    autolabor

    +

    autolabor

    Automatically manage dwarf labors.

    When enabled, autolabor periodically checks your dwarves and enables or disables labors. It tries to keep as many dwarves as possible busy but @@ -2525,14 +2536,14 @@ while it is enabled.

    -

    Other

    +

    Other

    -

    catsplosion

    +

    catsplosion

    Makes cats just multiply. It is not a good idea to run this more than once or twice.

    -

    dfusion

    +

    dfusion

    This is the DFusion lua plugin system by Warmist, running as a DFHack plugin. There are two parts to this plugin: an interactive script that shows a text based menu and lua modules. Some of the functionality of is intentionaly left out of the menu:
    @@ -2557,7 +2568,7 @@ twice.

    -

    misery

    +

    misery

    When enabled, every new negative dwarven thought will be multiplied by a factor (2 by default).

    Usage:

    @@ -2581,7 +2592,7 @@ twice.

    -

    Scripts

    +

    Scripts

    Lua or ruby scripts placed in the hack/scripts/ directory are considered for execution as if they were native DFHack commands. They are listed at the end of the 'ls' command output.

    @@ -2590,7 +2601,7 @@ only be listed by ls if called as 'ls -a'. This is intended as a way to hide scripts that are obscure, developer-oriented, or should be used as keybindings.

    Some notable scripts:

    -

    fix/*

    +

    fix/*

    Scripts in this subdirectory fix various bugs and issues, some of them obscure.

    • fix/dead-units

      @@ -2616,12 +2627,12 @@ caused by autodump bugs or other hacking mishaps.

    -

    gui/*

    +

    gui/*

    Scripts that implement dialogs inserted into the main game window are put in this directory.

    -

    binpatch

    +

    binpatch

    Checks, applies or removes binary patches directly in memory at runtime:

     binpatch check/apply/remove <patchname>
    @@ -2631,17 +2642,17 @@ script uses hack/patches/<df-v
     the version appropriate for the currently loaded executable.

    -

    quicksave

    +

    quicksave

    If called in dwarf mode, makes DF immediately auto-save the game by setting a flag normally used in seasonal auto-save.

    -

    setfps

    +

    setfps

    Run setfps <number> to set the FPS cap at runtime, in case you want to watch combat in slow motion or something :)

    -

    siren

    +

    siren

    Wakes up sleeping units, cancels breaks and stops parties either everywhere, or in the burrows given as arguments. In return, adds bad thoughts about noise, tiredness and lack of protection. Also, the units with interrupted @@ -2649,7 +2660,7 @@ breaks will go on break again a lot sooner. The script is intended for emergencies, e.g. when a siege appears, and all your military is partying.

    -

    growcrops

    +

    growcrops

    Instantly grow seeds inside farming plots.

    With no argument, this command list the various seed types currently in use in your farming plots. @@ -2661,7 +2672,7 @@ growcrops plump 40

    -

    removebadthoughts

    +

    removebadthoughts

    This script remove negative thoughts from your dwarves. Very useful against tantrum spirals.

    The script can target a single creature, when used with the him argument, @@ -2675,7 +2686,7 @@ but in the short term your dwarves will get much more joyful.

    quickly after you unpause.

    -

    slayrace

    +

    slayrace

    Kills any unit of a given race.

    With no argument, lists the available races.

    With the special argument him, targets only the selected creature.

    @@ -2701,7 +2712,7 @@ slayrace elve magma
    -

    magmasource

    +

    magmasource

    Create an infinite magma source on a tile.

    This script registers a map tile as a magma source, and every 12 game ticks that tile receives 1 new unit of flowing magma.

    @@ -2716,7 +2727,7 @@ To remove all placed sources, call magmasource stop

    With no argument, this command shows an help message and list existing sources.

    -

    digfort

    +

    digfort

    A script to designate an area for digging according to a plan in csv format.

    This script, inspired from quickfort, can designate an area for digging. Your plan should be stored in a .csv file like this:

    @@ -2734,7 +2745,7 @@ To skip a row in your design, use a single ;.<

    The script takes the plan filename, starting from the root df folder.

    -

    superdwarf

    +

    superdwarf

    Similar to fastdwarf, per-creature.

    To make any creature superfast, target it ingame using 'v' and:

    @@ -2744,16 +2755,16 @@ superdwarf add
     

    This plugin also shortens the 'sleeping' and 'on break' periods of targets.

    -

    drainaquifer

    +

    drainaquifer

    Remove all 'aquifer' tag from the map blocks. Irreversible.

    -

    deathcause

    +

    deathcause

    Focus a body part ingame, and this script will display the cause of death of the creature.

    -

    lua

    +

    lua

    There are the following ways to invoke this command:

    1. lua (without any parameters)

      @@ -2772,12 +2783,44 @@ directory. If the filename is not supplied, it loads "dfhack.lua".

    -

    embark

    +

    embark

    Allows to embark anywhere. Currently windows only.

    +
    +

    lever

    +

    Allow manipulation of in-game levers from the dfhack console.

    +

    Can list levers, including state and links, with:

    +
    +lever list
    +
    +

    To queue a job so that a dwarf will pull the lever 42, use lever pull 42. +This is the same as 'q'uerying the building and queue a 'P'ull request.

    +

    To magically toggle the lever immediately, use:

    +
    +lever pull 42 --now
    +
    +
    +
    +

    stripcaged

    +

    For dumping items inside cages. Will mark selected items for dumping, then +a dwarf may come and actually dump it. See also autodump.

    +

    With the items argument, only dumps items laying in the cage, excluding +stuff worn by caged creatures. weapons will dump worn weapons, armor +will dump everything worn by caged creatures (including armor and clothing), +and all will dump everything, on a creature or not.

    +

    stripcaged list will display on the dfhack console the list of all cages +and their item content.

    +

    Without further arguments, all commands work on all cages and animal traps on +the map. With the here argument, considers only the in-game selected cage +(or the cage under the game cursor). To target only specific cages, you can +alternatively pass cage IDs as arguments:

    +
    +stripcaged weapons 25321 34228
    +
    +
    -

    In-game interface tools

    +

    In-game interface tools

    These tools work by displaying dialogs or overlays in the game window, and are mostly implemented by lua scripts.

    @@ -2790,7 +2833,7 @@ existing DF screens, they deliberately use red instead of green for the key.

    guideline because it arguably just fixes small usability bugs in the game UI.

    -

    Dwarf Manipulator

    +

    Dwarf Manipulator

    Implemented by the manipulator plugin. To activate, open the unit screen and press 'l'.

    images/manipulator.png @@ -2798,8 +2841,10 @@ press 'l'.

    far left column displays the unit's Happiness (color-coded based on its value), and the right half of the screen displays each dwarf's labor settings and skill levels (0-9 for Dabbling thru Professional, A-E for Great thru Grand -Master, and U-Z for Legendary thru Legendary+5). Cells with red backgrounds -denote skills not controlled by labors.

    +Master, and U-Z for Legendary thru Legendary+5).

    +

    Cells with teal backgrounds denote skills not controlled by labors, e.g. +military and social skills.

    +images/manipulator2.png

    Use the arrow keys or number pad to move the cursor around, holding Shift to move 10 tiles at a time.

    Press the Z-Up (<) and Z-Down (>) keys to move quickly between labor/skill @@ -2827,7 +2872,7 @@ cursor onto that cell instead of toggling it. directly to the main dwarf mode screen.

    -

    AutoMaterial

    +

    AutoMaterial

    The automaterial plugin makes building constructions (walls, floors, fortifications, etc) a little bit easier by saving you from having to trawl through long lists of materials each time you place one.

    @@ -2874,14 +2919,14 @@ materials, it returns you back to this screen. If you use this along with severa enabled materials, you should be able to place complex constructions more conveniently.

    -

    gui/liquids

    +

    gui/liquids

    To use, bind to a key (the example config uses Alt-L) and activate in the 'k' mode.

    images/liquids.png

    While active, use the suggested keys to switch the usual liquids parameters, and Enter to select the target area and apply changes.

    -

    gui/mechanisms

    +

    gui/mechanisms

    To use, bind to a key (the example config uses Ctrl-M) and activate in the 'q' mode.

    images/mechanisms.png

    Lists mechanisms connected to the building, and their links. Navigating the list centers @@ -2891,7 +2936,7 @@ focus on the current one. Shift-Enter has an effect equivalent to pressing Enter re-entering the mechanisms ui.

    -

    gui/rename

    +

    gui/rename

    Backed by the rename plugin, this script allows entering the desired name via a simple dialog in the game ui.

      @@ -2914,7 +2959,7 @@ their species string.

      unit profession change to Ctrl-Shift-T.

    -

    gui/room-list

    +

    gui/room-list

    To use, bind to a key (the example config uses Alt-R) and activate in the 'q' mode, either immediately or after opening the assign owner page.

    images/room-list.png @@ -2922,7 +2967,7 @@ either immediately or after opening the assign owner page.

    list, and allows unassigning them.

    -

    gui/choose-weapons

    +

    gui/choose-weapons

    Bind to a key (the example config uses Ctrl-W), and activate in the Equip->View/Customize page of the military screen.

    Depending on the cursor location, it rewrites all 'individual choice weapon' entries @@ -2933,7 +2978,7 @@ only that entry, and does it even if it is not 'individual choice'.

    and may lead to inappropriate weapons being selected.

    -

    gui/guide-path

    +

    gui/guide-path

    Bind to a key (the example config uses Alt-P), and activate in the Hauling menu with the cursor over a Guide order.

    images/guide-path.png @@ -2941,7 +2986,7 @@ the cursor over a Guide order.

    computes it when the order is executed for the first time.

    -

    gui/workshop-job

    +

    gui/workshop-job

    Bind to a key (the example config uses Alt-A), and activate with a job selected in a workshop in the 'q' mode.

    images/workshop-job.png @@ -2977,7 +3022,7 @@ and then try to change the input item type, now it won't let you select plan you have to unset the material first.

    -

    gui/workflow

    +

    gui/workflow

    Bind to a key (the example config uses Alt-W), and activate with a job selected in a workshop in the 'q' mode.

    images/workflow.png @@ -3007,7 +3052,7 @@ suit your need, and set the item count range.

    If you don't need advanced settings, you can just press 'y' to confirm creation.

    -

    gui/assign-rack

    +

    gui/assign-rack

    Bind to a key (the example config uses P), and activate when viewing a weapon rack in the 'q' mode.

    images/assign-rack.png @@ -3032,7 +3077,7 @@ of currently assigned racks for every valid squad.

    -

    Behavior Mods

    +

    Behavior Mods

    These plugins, when activated via configuration UI or by detecting certain structures in RAWs, modify the game engine behavior concerning the target objects to add features not otherwise present.

    @@ -3043,20 +3088,20 @@ technical challenge, and do not represent any long-term plans to produce more similar modifications of the game.

    -

    Siege Engine

    +

    Siege Engine

    The siege-engine plugin enables siege engines to be linked to stockpiles, and aimed at an arbitrary rectangular area across Z levels, instead of the original four directions. Also, catapults can be ordered to load arbitrary objects, not just stones.

    -

    Rationale

    +

    Rationale

    Siege engines are a very interesting feature, but sadly almost useless in the current state because they haven't been updated since 2D and can only aim in four directions. This is an attempt to bring them more up to date until Toady has time to work on it. Actual improvements, e.g. like making siegers bring their own, are something only Toady can do.

    -

    Configuration UI

    +

    Configuration UI

    The configuration front-end to the plugin is implemented by the gui/siege-engine script. Bind it to a key (the example config uses Alt-A) and activate after selecting a siege engine in 'q' mode.

    @@ -3079,7 +3124,7 @@ menu.

    -

    Power Meter

    +

    Power Meter

    The power-meter plugin implements a modified pressure plate that detects power being supplied to gear boxes built in the four adjacent N/S/W/E tiles.

    The configuration front-end is implemented by the gui/power-meter script. Bind it to a @@ -3090,11 +3135,11 @@ in the build menu.

    configuration page, but configures parameters relevant to the modded power meter building.

    -

    Steam Engine

    +

    Steam Engine

    The steam-engine plugin detects custom workshops with STEAM_ENGINE in their token, and turns them into real steam engines.

    -

    Rationale

    +

    Rationale

    The vanilla game contains only water wheels and windmills as sources of power, but windmills give relatively little power, and water wheels require flowing water, which must either be a real river and thus immovable and @@ -3105,7 +3150,7 @@ it can be done just by combining existing features of the game engine in a new way with some glue code and a bit of custom logic.

    -

    Construction

    +

    Construction

    The workshop needs water as its input, which it takes via a passable floor tile below it, like usual magma workshops do. The magma version also needs magma.

    @@ -3129,7 +3174,7 @@ short axles that can be built later than both of the engines.

    -

    Operation

    +

    Operation

    In order to operate the engine, queue the Stoke Boiler job (optionally on repeat). A furnace operator will come, possibly bringing a bar of fuel, and perform it. As a result, a "boiling water" item will appear @@ -3160,7 +3205,7 @@ decrease it by further 4%, and also decrease the whole steam use rate by 10%.

    -

    Explosions

    +

    Explosions

    The engine must be constructed using barrel, pipe and piston from fire-safe, or in the magma version magma-safe metals.

    During operation weak parts get gradually worn out, and @@ -3169,7 +3214,7 @@ toppled during operation by a building destroyer, or a tantruming dwarf.

    -

    Save files

    +

    Save files

    It should be safe to load and view engine-using fortresses from a DF version without DFHack installed, except that in such case the engines won't work. However actually making modifications @@ -3180,7 +3225,7 @@ being generated.

    -

    Add Spatter

    +

    Add Spatter

    This plugin makes reactions with names starting with SPATTER_ADD_ produce contaminants on the items instead of improvements. The produced contaminants are immune to being washed away by water or destroyed by diff --git a/Readme.rst b/Readme.rst index 3434a240d..b9844debd 100644 --- a/Readme.rst +++ b/Readme.rst @@ -2032,8 +2032,12 @@ This tool implements a Dwarf Therapist-like interface within the game UI. The far left column displays the unit's Happiness (color-coded based on its value), and the right half of the screen displays each dwarf's labor settings and skill levels (0-9 for Dabbling thru Professional, A-E for Great thru Grand -Master, and U-Z for Legendary thru Legendary+5). Cells with red backgrounds -denote skills not controlled by labors. +Master, and U-Z for Legendary thru Legendary+5). + +Cells with teal backgrounds denote skills not controlled by labors, e.g. +military and social skills. + +.. image:: images/manipulator2.png Use the arrow keys or number pad to move the cursor around, holding Shift to move 10 tiles at a time. diff --git a/images/manipulator.png b/images/manipulator.png index 0a546034557fceb446aa0ccb8ddb51883fd71a84..44b603600b36d2954163982c2ad4aa37a36b12e6 100644 GIT binary patch literal 9024 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 E09@dZ(*OVf literal 0 HcmV?d00001 From 46fb69663b492802ac5994c031adaa7cfb9e4d81 Mon Sep 17 00:00:00 2001 From: Quietust Date: Tue, 27 Nov 2012 11:55:53 -0600 Subject: [PATCH 24/35] Pack manipulator screenshots --- images/manipulator.png | Bin 9024 -> 7724 bytes images/manipulator2.png | Bin 8840 -> 7558 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/manipulator.png b/images/manipulator.png index 44b603600b36d2954163982c2ad4aa37a36b12e6..1f452549f9e0abc9998f298eb19a9a3650ee1ed5 100644 GIT binary patch delta 7708 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 Zeu72+NY;{iUj_yS22WQ%mvv4FO#lkZi8}xQ delta 8832 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 DqJW+i From 8f0d552556ef139f6b51f56abee910c4623223a3 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 28 Nov 2012 13:33:07 +0100 Subject: [PATCH 25/35] ruby: add DFHack::VERSION --- plugins/ruby/ruby.cpp | 7 +++++++ plugins/ruby/ruby.rb | 2 ++ 2 files changed, 9 insertions(+) diff --git a/plugins/ruby/ruby.cpp b/plugins/ruby/ruby.cpp index 13190f70d..db94ad650 100644 --- a/plugins/ruby/ruby.cpp +++ b/plugins/ruby/ruby.cpp @@ -438,6 +438,12 @@ static VALUE rb_cDFHack; // DFHack module ruby methods, binds specific dfhack methods +// df-dfhack version (eg "0.34.11-r2") +static VALUE rb_dfversion(VALUE self) +{ + return rb_str_new(DFHACK_VERSION, strlen(DFHACK_VERSION)); +} + // enable/disable calls to DFHack.onupdate() static VALUE rb_dfonupdate_active(VALUE self) { @@ -955,6 +961,7 @@ static void ruby_bind_dfhack(void) { rb_define_singleton_method(rb_cDFHack, "malloc", RUBY_METHOD_FUNC(rb_dfmalloc), 1); rb_define_singleton_method(rb_cDFHack, "free", RUBY_METHOD_FUNC(rb_dffree), 1); rb_define_singleton_method(rb_cDFHack, "vmethod_do_call", RUBY_METHOD_FUNC(rb_dfvcall), 8); + rb_define_singleton_method(rb_cDFHack, "version", RUBY_METHOD_FUNC(rb_dfversion), 0); rb_define_singleton_method(rb_cDFHack, "memory_read", RUBY_METHOD_FUNC(rb_dfmemory_read), 2); rb_define_singleton_method(rb_cDFHack, "memory_read_int8", RUBY_METHOD_FUNC(rb_dfmemory_read_int8), 1); diff --git a/plugins/ruby/ruby.rb b/plugins/ruby/ruby.rb index b7f7590e9..27cde675a 100644 --- a/plugins/ruby/ruby.rb +++ b/plugins/ruby/ruby.rb @@ -23,6 +23,8 @@ module Kernel end module DFHack + VERSION = version + class OnupdateCallback attr_accessor :callback, :timelimit, :minyear, :minyeartick, :description def initialize(descr, cb, tl, initdelay=0) From 593dc4f55486b02a258953558db2054cd3607123 Mon Sep 17 00:00:00 2001 From: Anuradha Dissanayake Date: Sun, 25 Nov 2012 19:01:58 +1300 Subject: [PATCH 26/35] Fix handling of manipulator hotkey in unit search screen --- plugins/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/search.cpp b/plugins/search.cpp index 742fa9277..a14397fba 100644 --- a/plugins/search.cpp +++ b/plugins/search.cpp @@ -521,7 +521,8 @@ private: virtual bool should_check_input(set *input) { - if (input->count(interface_key::CURSOR_LEFT) || input->count(interface_key::CURSOR_RIGHT) || input->count(interface_key::CUSTOM_L)) + if (input->count(interface_key::CURSOR_LEFT) || input->count(interface_key::CURSOR_RIGHT) || + (!is_entry_mode() && input->count(interface_key::UNITVIEW_PRF_PROF))) { if (!is_entry_mode()) { From bfc11cf94636856a55d0a26ddcd139d41c3d11e1 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 28 Nov 2012 19:25:01 +0400 Subject: [PATCH 27/35] Add persistent history of per-constraint item counts in workflow. This will be needed for properly merging or integrating the status screen by falconne. The history is maintained as a circular buffer of up to 28 entries, and persists in save files. --- library/include/modules/World.h | 49 ++++++++++++++++ plugins/workflow.cpp | 101 +++++++++++++++++++++++++++++--- 2 files changed, 143 insertions(+), 7 deletions(-) diff --git a/library/include/modules/World.h b/library/include/modules/World.h index a945c4e72..f1fea52a1 100644 --- a/library/include/modules/World.h +++ b/library/include/modules/World.h @@ -81,6 +81,55 @@ namespace DFHack int &ival(int i) { return int_values[i]; } int ival(int i) const { return int_values[i]; } + // Pack binary data into string field. + // Since DF serialization chokes on NUL bytes, + // use bit magic to ensure none of the bytes is 0. + // Choose the lowest bit for padding so that + // sign-extend can be used normally. + + size_t data_size() const { return str_value->size(); } + + bool check_data(size_t off, size_t sz = 1) { + return (str_value->size() >= off+sz); + } + void ensure_data(size_t off, size_t sz = 0) { + if (str_value->size() < off+sz) str_value->resize(off+sz, '\x01'); + } + uint8_t *pdata(size_t off) { return (uint8_t*)&(*str_value)[off]; } + + static const size_t int7_size = 1; + uint8_t get_uint7(size_t off) { + uint8_t *p = pdata(off); + return p[0]>>1; + } + int8_t get_int7(size_t off) { + uint8_t *p = pdata(off); + return int8_t(p[0])>>1; + } + void set_uint7(size_t off, uint8_t val) { + uint8_t *p = pdata(off); + p[0] = uint8_t((val<<1) | 1); + } + void set_int7(size_t off, int8_t val) { set_uint7(off, val); } + + static const size_t int28_size = 4; + uint32_t get_uint28(size_t off) { + uint8_t *p = pdata(off); + return (p[0]>>1) | ((p[1]&~1U)<<6) | ((p[2]&~1U)<<13) | ((p[3]&~1U)<<20); + } + int32_t get_int28(size_t off) { + uint8_t *p = pdata(off); + return (p[0]>>1) | ((p[1]&~1U)<<6) | ((p[2]&~1U)<<13) | ((int8_t(p[3])&~1)<<20); + } + void set_uint28(size_t off, uint32_t val) { + uint8_t *p = pdata(off); + p[0] = uint8_t((val<<1) | 1); + p[1] = uint8_t((val>>6) | 1); + p[2] = uint8_t((val>>13) | 1); + p[3] = uint8_t((val>>20) | 1); + } + void set_int28(size_t off, int32_t val) { set_uint28(off, val); } + PersistentDataItem() : id(0), str_value(0), int_values(0) {} PersistentDataItem(int id, const std::string &key, std::string *sv, int *iv) : id(id), key_value(key), str_value(sv), int_values(iv) {} diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 6e15a4537..813326175 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -293,6 +293,7 @@ typedef std::map, bool> TMaterialCache; struct ItemConstraint { PersistentDataItem config; + PersistentDataItem history; // Fixed key parsed into fields bool is_craft; @@ -308,7 +309,7 @@ struct ItemConstraint { int weight; std::vector jobs; - int item_amount, item_count, item_inuse; + int item_amount, item_count, item_inuse_amount, item_inuse_count; bool request_suspend, request_resume; bool is_active, cant_resume_reported; @@ -318,7 +319,7 @@ struct ItemConstraint { public: ItemConstraint() : is_craft(false), min_quality(item_quality::Ordinary), is_local(false), - weight(0), item_amount(0), item_count(0), item_inuse(0), + weight(0), item_amount(0), item_count(0), item_inuse_amount(0), item_inuse_count(0), is_active(false), cant_resume_reported(false) {} @@ -352,6 +353,44 @@ public: request_resume = (size <= goalCount()-goalGap()); request_suspend = (size >= goalCount()); } + + static const size_t int28_size = PersistentDataItem::int28_size; + static const size_t hist_entry_size = PersistentDataItem::int28_size * 4; + + size_t history_size() { + return history.data_size() / hist_entry_size; + } + size_t history_base(int idx) { + size_t hsize = history_size(); + return ((history.ival(0)+hsize-idx) % hsize) * hist_entry_size; + } + int history_count(int idx) { + return history.get_int28(history_base(idx) + 0*int28_size); + } + int history_amount(int idx) { + return history.get_int28(history_base(idx) + 1*int28_size); + } + int history_inuse_count(int idx) { + return history.get_int28(history_base(idx) + 2*int28_size); + } + int history_inuse_amount(int idx) { + return history.get_int28(history_base(idx) + 3*int28_size); + } + + void updateHistory() + { + size_t buffer_size = history_size(); + if (buffer_size < 28) + history.ensure_data(hist_entry_size*buffer_size++, hist_entry_size); + history.ival(0) = (history.ival(0)+1) % buffer_size; + + size_t base = history.ival(0) * hist_entry_size; + + history.set_int28(base + 0*int28_size, item_count); + history.set_int28(base + 1*int28_size, item_amount); + history.set_int28(base + 2*int28_size, item_inuse_count); + history.set_int28(base + 3*int28_size, item_inuse_amount); + } }; /****************************** @@ -649,6 +688,9 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) update_job_data(out); process_constraints(out); + + for (size_t i = 0; i < constraints.size(); i++) + constraints[i]->updateHistory(); } } @@ -659,6 +701,10 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) * ITEM COUNT CONSTRAINT * ******************************/ +static std::string history_key(PersistentDataItem &config) { + return stl_sprintf("workflow/history/%d", config.entry_id()); +} + static ItemConstraint *get_constraint(color_ostream &out, const std::string &str, PersistentDataItem *cfg, bool create) { std::vector tokens; @@ -776,6 +822,8 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str nct->init(str); } + nct->history = World::GetPersistentData(history_key(nct->config), NULL); + constraints.push_back(nct); return nct; } @@ -787,6 +835,7 @@ static void delete_constraint(ItemConstraint *cv) vector_erase_at(constraints, idx); World::DeletePersistentData(cv->config); + World::DeletePersistentData(cv->history); delete cv; } @@ -1064,7 +1113,8 @@ static void map_job_items(color_ostream &out) { constraints[i]->item_amount = 0; constraints[i]->item_count = 0; - constraints[i]->item_inuse = 0; + constraints[i]->item_inuse_amount = 0; + constraints[i]->item_inuse_count = 0; } meltable_count = 0; @@ -1177,7 +1227,8 @@ static void map_job_items(color_ostream &out) isAssignedSquad(item)) { is_invalid = true; - cv->item_inuse++; + cv->item_inuse_count++; + cv->item_inuse_amount += item->getStackSize(); } else { @@ -1367,7 +1418,8 @@ static void push_constraint(lua_State *L, ItemConstraint *cv) Lua::SetField(L, cv->item_amount, ctable, "cur_amount"); Lua::SetField(L, cv->item_count, ctable, "cur_count"); - Lua::SetField(L, cv->item_inuse, ctable, "cur_in_use"); + Lua::SetField(L, cv->item_inuse_amount, ctable, "cur_in_use_amount"); + Lua::SetField(L, cv->item_inuse_count, ctable, "cur_in_use_count"); // Current state value @@ -1463,6 +1515,40 @@ static int setConstraint(lua_State *L) return 1; } +static int getCountHistory(lua_State *L) +{ + auto token = luaL_checkstring(L, 1); + + color_ostream &out = *Lua::GetOutput(L); + update_data_structures(out); + + ItemConstraint *icv = get_constraint(out, token, NULL, false); + + if (icv) + { + size_t hsize = icv->history_size(); + + lua_createtable(L, hsize, 0); + + for (int i = hsize-1; i >= 0; i--) + { + lua_createtable(L, 0, 4); + + Lua::SetField(L, icv->history_amount(i), -1, "cur_amount"); + Lua::SetField(L, icv->history_count(i), -1, "cur_count"); + Lua::SetField(L, icv->history_inuse_amount(i), -1, "cur_in_use_amount"); + Lua::SetField(L, icv->history_inuse_count(i), -1, "cur_in_use_count"); + + lua_rawseti(L, -2, hsize-i); // reverse order + } + } + else + lua_pushnil(L); + + return 1; +} + + DFHACK_PLUGIN_LUA_FUNCTIONS { DFHACK_LUA_FUNCTION(isEnabled), DFHACK_LUA_FUNCTION(setEnabled), @@ -1474,6 +1560,7 @@ DFHACK_PLUGIN_LUA_COMMANDS { DFHACK_LUA_COMMAND(listConstraints), DFHACK_LUA_COMMAND(findConstraint), DFHACK_LUA_COMMAND(setConstraint), + DFHACK_LUA_COMMAND(getCountHistory), DFHACK_LUA_END }; @@ -1521,10 +1608,10 @@ static void print_constraint(color_ostream &out, ItemConstraint *cv, bool no_job << cv->goalCount() << " (gap " << cv->goalGap() << ")" << endl; out.reset_color(); - if (cv->item_count || cv->item_inuse) + if (cv->item_count || cv->item_inuse_count) out << prefix << " items: amount " << cv->item_amount << "; " << cv->item_count << " stacks available, " - << cv->item_inuse << " in use." << endl; + << cv->item_inuse_count << " in use." << endl; if (no_job) return; From 614225cc5f62ea6ccb6743ae38a32cec5e6270f8 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 28 Nov 2012 19:46:56 +0100 Subject: [PATCH 28/35] follow rename itemst.flags.artifact1 -> artifact --- plugins/autodump.cpp | 4 ++-- plugins/autolabor.cpp | 2 +- plugins/devel/stockcheck.cpp | 2 +- plugins/workflow.cpp | 2 +- scripts/autofarm.rb | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/autodump.cpp b/plugins/autodump.cpp index 5eb25964e..5b4804647 100644 --- a/plugins/autodump.cpp +++ b/plugins/autodump.cpp @@ -161,7 +161,7 @@ static command_result autodump_main(color_ostream &out, vector & parame || itm->flags.bits.in_building || itm->flags.bits.in_chest // || itm->flags.bits.in_inventory - || itm->flags.bits.artifact1 + || itm->flags.bits.artifact ) continue; @@ -271,7 +271,7 @@ command_result df_autodump_destroy_item(color_ostream &out, vector & pa if (item->flags.bits.construction || item->flags.bits.in_building || - item->flags.bits.artifact1) + item->flags.bits.artifact) { out.printerr("Choosing not to destroy buildings, constructions and artifacts.\n"); return CR_FAILURE; diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp index 83718bd09..e5047b434 100644 --- a/plugins/autolabor.cpp +++ b/plugins/autolabor.cpp @@ -1556,7 +1556,7 @@ static int stockcheck(color_ostream &out, vector & parameters) #define F(x) bad_flags.bits.x = true; F(dump); F(forbid); F(garbage_collect); F(hostile); F(on_fire); F(rotten); F(trader); - F(in_building); F(construction); F(artifact1); + F(in_building); F(construction); F(artifact); F(spider_web); F(owned); F(in_job); #undef F diff --git a/plugins/devel/stockcheck.cpp b/plugins/devel/stockcheck.cpp index 666db0d79..679411b0e 100644 --- a/plugins/devel/stockcheck.cpp +++ b/plugins/devel/stockcheck.cpp @@ -144,7 +144,7 @@ static command_result stockcheck(color_ostream &out, vector & parameter #define F(x) bad_flags.bits.x = true; F(dump); F(forbid); F(garbage_collect); F(hostile); F(on_fire); F(rotten); F(trader); - F(in_building); F(construction); F(artifact1); + F(in_building); F(construction); F(artifact); F(spider_web); F(owned); F(in_job); #undef F diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 813326175..05fdca55b 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -1126,7 +1126,7 @@ static void map_job_items(color_ostream &out) #define F(x) bad_flags.bits.x = true; F(dump); F(forbid); F(garbage_collect); F(hostile); F(on_fire); F(rotten); F(trader); - F(in_building); F(construction); F(artifact1); + F(in_building); F(construction); F(artifact); #undef F bool dry_buckets = isOptionEnabled(CF_DRYBUCKETS); diff --git a/scripts/autofarm.rb b/scripts/autofarm.rb index c89cb9ff4..cd381089e 100644 --- a/scripts/autofarm.rb +++ b/scripts/autofarm.rb @@ -66,7 +66,7 @@ class AutoFarm if (!i.flags.dump && !i.flags.forbid && !i.flags.garbage_collect && !i.flags.hostile && !i.flags.on_fire && !i.flags.rotten && !i.flags.trader && !i.flags.in_building && !i.flags.construction && - !i.flags.artifact1 && plantable.has_key?(i.mat_index)) + !i.flags.artifact && plantable.has_key?(i.mat_index)) counts[i.mat_index] = counts[i.mat_index] + i.stack_size end } From 771a5ac50bfae154773a4b083277ec81ffa38148 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 28 Nov 2012 20:08:34 +0100 Subject: [PATCH 29/35] ruby: tweak flagarray#inspect --- plugins/ruby/ruby-autogen-defs.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/ruby/ruby-autogen-defs.rb b/plugins/ruby/ruby-autogen-defs.rb index c3203bd52..4148659a6 100644 --- a/plugins/ruby/ruby-autogen-defs.rb +++ b/plugins/ruby/ruby-autogen-defs.rb @@ -138,7 +138,6 @@ module DFHack @@inspecting = {} # avoid infinite recursion on mutually-referenced objects def inspect cn = self.class.name.sub(/^DFHack::/, '') - cn << ' @' << ('0x%X' % _memaddr) if cn != '' out = "#<#{cn}" return out << ' ...>' if @@inspecting[_memaddr] @@inspecting[_memaddr] = true @@ -655,6 +654,13 @@ module DFHack DFHack.memory_bitarray_set(@_memaddr, idx, v) end end + def inspect + out = "#' + end include Enumerable end From 94e669058604b8a129ff431164a987b951f15f0d Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 29 Nov 2012 13:37:16 +0400 Subject: [PATCH 30/35] Don't complain about fake input tokens in simulateInput. --- library/lua/gui.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/lua/gui.lua b/library/lua/gui.lua index cfb058f9d..2145cfad1 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -10,13 +10,19 @@ local to_pen = dfhack.pen.parse CLEAR_PEN = to_pen{ch=32,fg=0,bg=0} +local FAKE_INPUT_KEYS = { + _MOUSE_L = true, + _MOUSE_R = true, + _STRING = true, +} + function simulateInput(screen,...) local keys = {} local function push_key(arg) local kv = arg if type(arg) == 'string' then kv = df.interface_key[arg] - if kv == nil then + if kv == nil and not FAKE_INPUT_KEYS[arg] then error('Invalid keycode: '..arg) end end From 5ea26d9cae7ae43da8afdac905c7b3ab96f9991d Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 29 Nov 2012 16:27:51 +0400 Subject: [PATCH 31/35] Only show the advanced new constraint dialog on Shift-Enter. Upon reflection it is a bit too scary to be always shown. --- Lua API.html | 6 ++++++ Lua API.rst | 6 ++++++ Readme.html | 4 ++-- Readme.rst | 6 ++---- images/workflow-new1.png | Bin 5662 -> 6674 bytes library/lua/gui/dialogs.lua | 22 +++++++++++++++++++++- library/lua/gui/widgets.lua | 19 +++++++++++++++++++ scripts/gui/workflow.lua | 20 ++++++++++++-------- 8 files changed, 68 insertions(+), 15 deletions(-) diff --git a/Lua API.html b/Lua API.html index 04af5d672..f42905d01 100644 --- a/Lua API.html +++ b/Lua API.html @@ -2853,6 +2853,9 @@ this may be extended with mouse click support.

    + +
    on_submit:Enter key callback; if specified, the list reacts to the key and calls it as on_submit(index,choice).
    on_submit2:Shift-Enter key callback; if specified, the list reacts to the key +and calls it as on_submit2(index,choice).
    row_height:Height of every row in text lines.
    icon_width:If not nil, the specified number of character columns @@ -2908,6 +2911,9 @@ with the following fields:

  • list:submit()

    Call the on_submit callback, as if the Enter key was handled.

  • +
  • list:submit2()

    +

    Call the on_submit2 callback, as if the Shift-Enter key was handled.

    +
  • diff --git a/Lua API.rst b/Lua API.rst index 4087ff0aa..d42a348e4 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -2777,6 +2777,8 @@ It has the following attributes: :on_select: Selection change callback; called as ``on_select(index,choice)``. :on_submit: Enter key callback; if specified, the list reacts to the key and calls it as ``on_submit(index,choice)``. +:on_submit2: Shift-Enter key callback; if specified, the list reacts to the key + and calls it as ``on_submit2(index,choice)``. :row_height: Height of every row in text lines. :icon_width: If not *nil*, the specified number of character columns are reserved to the left of the list item for the icons. @@ -2826,6 +2828,10 @@ The list supports the following methods: Call the ``on_submit`` callback, as if the Enter key was handled. +* ``list:submit2()`` + + Call the ``on_submit2`` callback, as if the Shift-Enter key was handled. + FilteredList class ------------------ diff --git a/Readme.html b/Readme.html index cdc4dd631..deea72bef 100644 --- a/Readme.html +++ b/Readme.html @@ -3045,11 +3045,11 @@ the job material first using job as described in workflow documentation above. In this manner, this feature can be used for troubleshooting jobs that don't match the right constraints.

    images/workflow-new1.png -

    After selecting one of the presented outputs, the interface proceeds to the +

    If you select one of the outputs with Enter, the matching constraint is simply +added to the list. If you use Shift-Enter, the interface proceeds to the next dialog, which allows you to edit the suggested constraint parameters to suit your need, and set the item count range.

    images/workflow-new2.png -

    If you don't need advanced settings, you can just press 'y' to confirm creation.

    gui/assign-rack

    diff --git a/Readme.rst b/Readme.rst index b9844debd..a214a6ecb 100644 --- a/Readme.rst +++ b/Readme.rst @@ -2309,15 +2309,13 @@ can be used for troubleshooting jobs that don't match the right constraints. .. image:: images/workflow-new1.png -After selecting one of the presented outputs, the interface proceeds to the +If you select one of the outputs with Enter, the matching constraint is simply +added to the list. If you use Shift-Enter, the interface proceeds to the next dialog, which allows you to edit the suggested constraint parameters to suit your need, and set the item count range. .. image:: images/workflow-new2.png -If you don't need advanced settings, you can just press 'y' to confirm creation. - - gui/assign-rack =============== diff --git a/images/workflow-new1.png b/images/workflow-new1.png index 25b498bca23326f9e5ea05471dfcdb275f4e4734..50d0e1f421ac9de1abf87545c8d7ade31bd4cd4a 100644 GIT binary patch literal 6674 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 literal 5662 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 diff --git a/library/lua/gui/dialogs.lua b/library/lua/gui/dialogs.lua index 0a79b4c3e..fb9b8fd63 100644 --- a/library/lua/gui/dialogs.lua +++ b/library/lua/gui/dialogs.lua @@ -152,7 +152,9 @@ ListBox.ATTRS{ with_filter = false, cursor_pen = DEFAULT_NIL, select_pen = DEFAULT_NIL, - on_select = DEFAULT_NIL + on_select = DEFAULT_NIL, + on_select2 = DEFAULT_NIL, + select2_hint = DEFAULT_NIL, } function ListBox:preinit(info) @@ -168,6 +170,16 @@ function ListBox:init(info) list_widget = widgets.FilteredList end + local on_submit2 + if self.select2_hint or self.on_select2 then + on_submit2 = function(sel, obj) + self:dismiss() + if self.on_select2 then self.on_select2(sel, obj) end + local cb = obj.on_select2 + if cb then cb(obj, sel) end + end + end + self:addviews{ list_widget{ view_id = 'list', @@ -182,11 +194,19 @@ function ListBox:init(info) local cb = obj.on_select or obj[2] if cb then cb(obj, sel) end end, + on_submit2 = on_submit2, frame = { l = 0, r = 0 }, } } end +function ListBox:onRenderFrame(dc,rect) + ListBox.super.onRenderFrame(self,dc,rect) + if self.select2_hint then + dc:seek(rect.x1+2,rect.y2):key('SEC_SELECT'):string(': '..self.select2_hint,COLOR_DARKGREY) + end +end + function ListBox:getWantedFrameSize() local mw, mh = InputBox.super.getWantedFrameSize(self) local list = self.subviews.list diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 67090e114..145300c59 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -384,6 +384,7 @@ List.ATTRS{ inactive_pen = DEFAULT_NIL, on_select = DEFAULT_NIL, on_submit = DEFAULT_NIL, + on_submit2 = DEFAULT_NIL, row_height = 1, scroll_keys = STANDARDSCROLL, icon_width = DEFAULT_NIL, @@ -542,10 +543,19 @@ function List:submit() end end +function List:submit2() + if self.on_submit2 and #self.choices > 0 then + self.on_submit2(self:getSelected()) + end +end + function List:onInput(keys) if self.on_submit and keys.SELECT then self:submit() return true + elseif self.on_submit2 and keys.SEC_SELECT then + self:submit2() + return true else for k,v in pairs(self.scroll_keys) do if keys[k] then @@ -608,6 +618,11 @@ function FilteredList:init(info) return info.on_submit(self:getSelected()) end end + if info.on_submit2 then + self.list.on_submit2 = function() + return info.on_submit2(self:getSelected()) + end + end self.not_found = Label{ visible = false, text = info.not_found_label or 'No matches', @@ -634,6 +649,10 @@ function FilteredList:submit() return self.list:submit() end +function FilteredList:submit2() + return self.list:submit2() +end + function FilteredList:canSubmit() return not self.not_found.visible end diff --git a/scripts/gui/workflow.lua b/scripts/gui/workflow.lua index 80c05d296..a387e64b9 100644 --- a/scripts/gui/workflow.lua +++ b/scripts/gui/workflow.lua @@ -552,18 +552,22 @@ function JobConstraints:onNewConstraint() table.insert(choices, { text = itemstr..' of '..matstr, obj = cons }) end - dlg.showListPrompt( - 'New limit', - 'Select one of the possible outputs:', - COLOR_WHITE, - choices, - function(idx,item) + dlg.ListBox{ + frame_title = 'New limit', + text = 'Select one of the possible outputs:', + text_pen = COLOR_WHITE, + choices = choices, + on_select = function(idx,item) + self:saveConstraint(item.obj) + end, + select2_hint = 'Advanced', + on_select2 = function(idx,item) NewConstraint{ constraint = item.obj, on_submit = self:callback('saveConstraint') }:show() - end - ) + end, + }:show() end function JobConstraints:onDeleteConstraint() From d7f7538d0148e8a731089034f431dfcd80c3a268 Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 29 Nov 2012 10:33:18 +0100 Subject: [PATCH 32/35] ruby: fix Pointer assignment --- plugins/ruby/ruby-autogen-defs.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ruby/ruby-autogen-defs.rb b/plugins/ruby/ruby-autogen-defs.rb index 4148659a6..a3e810178 100644 --- a/plugins/ruby/ruby-autogen-defs.rb +++ b/plugins/ruby/ruby-autogen-defs.rb @@ -308,7 +308,7 @@ module DFHack DFHack.memory_write_int32(@_memaddr, v) end when nil; DFHack.memory_write_int32(@_memaddr, 0) - else _get._set(v) + else @_tg._at(_getp)._set(v) end end From 184082b379c67989c55d5454cc3a204b40d71360 Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 29 Nov 2012 17:11:16 +0100 Subject: [PATCH 33/35] scripts/lever: fix for links to cage/support --- scripts/lever.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/lever.rb b/scripts/lever.rb index 59196f7d2..43aa29b04 100644 --- a/scripts/lever.rb +++ b/scripts/lever.rb @@ -47,9 +47,12 @@ def lever_descr(bld, idx=nil) }.flatten.each { |r| # linked building description tg = r.building_tg - state = tg.gate_flags.closed ? 'closed' : 'opened' - state << ', closing' if tg.gate_flags.closing - state << ', opening' if tg.gate_flags.opening + state = '' + if tg.respond_to?(:gate_flags) + state << (tg.gate_flags.closed ? 'closed' : 'opened') + state << ", closing (#{tg.timer})" if tg.gate_flags.closing + state << ", opening (#{tg.timer})" if tg.gate_flags.opening + end ret << (descr + " linked to #{tg._rtti_classname} ##{tg.id} @[#{tg.centerx}, #{tg.centery}, #{tg.z}] #{state}") From 2cb594ba8990e062e7f353d38811b218f631866b Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 30 Nov 2012 14:48:05 +0400 Subject: [PATCH 34/35] Tweak the workflow lua api: include history in output of listConstraints. --- plugins/lua/workflow.lua | 3 +- plugins/workflow.cpp | 98 +++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/plugins/lua/workflow.lua b/plugins/lua/workflow.lua index 19ca0a84a..b3bcf3d08 100644 --- a/plugins/lua/workflow.lua +++ b/plugins/lua/workflow.lua @@ -8,10 +8,11 @@ local utils = require 'utils' * isEnabled() * setEnabled(enable) - * listConstraints([job]) -> {...} + * listConstraints([job[,with_history]]) -> {{...},...} * findConstraint(token) -> {...} or nil * setConstraint(token[, by_count, goal, gap]) -> {...} * deleteConstraint(token) -> true/false + * getCountHistory(token) -> {{...},...} or nil --]] diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 05fdca55b..12174af5c 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -291,6 +291,15 @@ int ProtectedJob::cur_tick_idx = 0; typedef std::map, bool> TMaterialCache; +static const size_t MAX_HISTORY_SIZE = 28; + +enum HistoryItem { + HIST_COUNT = 0, + HIST_AMOUNT, + HIST_INUSE_COUNT, + HIST_INUSE_AMOUNT +}; + struct ItemConstraint { PersistentDataItem config; PersistentDataItem history; @@ -360,36 +369,29 @@ public: size_t history_size() { return history.data_size() / hist_entry_size; } - size_t history_base(int idx) { + int history_value(int idx, HistoryItem item) { size_t hsize = history_size(); - return ((history.ival(0)+hsize-idx) % hsize) * hist_entry_size; - } - int history_count(int idx) { - return history.get_int28(history_base(idx) + 0*int28_size); - } - int history_amount(int idx) { - return history.get_int28(history_base(idx) + 1*int28_size); - } - int history_inuse_count(int idx) { - return history.get_int28(history_base(idx) + 2*int28_size); - } - int history_inuse_amount(int idx) { - return history.get_int28(history_base(idx) + 3*int28_size); + size_t base = ((history.ival(0)+1+idx) % hsize) * hist_entry_size; + return history.get_int28(base + item*int28_size); } + int history_count(int idx) { return history_value(idx, HIST_COUNT); } + int history_amount(int idx) { return history_value(idx, HIST_AMOUNT); } + int history_inuse_count(int idx) { return history_value(idx, HIST_INUSE_COUNT); } + int history_inuse_amount(int idx) { return history_value(idx, HIST_INUSE_AMOUNT); } void updateHistory() { size_t buffer_size = history_size(); - if (buffer_size < 28) - history.ensure_data(hist_entry_size*buffer_size++, hist_entry_size); + if (buffer_size < MAX_HISTORY_SIZE && size_t(history.ival(0)+1) == buffer_size) + history.ensure_data(hist_entry_size*++buffer_size); history.ival(0) = (history.ival(0)+1) % buffer_size; size_t base = history.ival(0) * hist_entry_size; - history.set_int28(base + 0*int28_size, item_count); - history.set_int28(base + 1*int28_size, item_amount); - history.set_int28(base + 2*int28_size, item_inuse_count); - history.set_int28(base + 3*int28_size, item_inuse_amount); + history.set_int28(base + HIST_COUNT*int28_size, item_count); + history.set_int28(base + HIST_AMOUNT*int28_size, item_amount); + history.set_int28(base + HIST_INUSE_COUNT*int28_size, item_inuse_count); + history.set_int28(base + HIST_INUSE_AMOUNT*int28_size, item_inuse_amount); } }; @@ -1384,6 +1386,25 @@ static void setEnabled(color_ostream &out, bool enable) } } +static void push_count_history(lua_State *L, ItemConstraint *icv) +{ + size_t hsize = icv->history_size(); + + lua_createtable(L, hsize, 0); + + for (size_t i = 0; i < hsize; i++) + { + lua_createtable(L, 0, 4); + + Lua::SetField(L, icv->history_amount(i), -1, "cur_amount"); + Lua::SetField(L, icv->history_count(i), -1, "cur_count"); + Lua::SetField(L, icv->history_inuse_amount(i), -1, "cur_in_use_amount"); + Lua::SetField(L, icv->history_inuse_count(i), -1, "cur_in_use_count"); + + lua_rawseti(L, -2, i+1); + } +} + static void push_constraint(lua_State *L, ItemConstraint *cv) { lua_newtable(L); @@ -1430,19 +1451,31 @@ static void push_constraint(lua_State *L, ItemConstraint *cv) lua_newtable(L); + bool resumed = false, want_resumed = false; + for (size_t i = 0, j = 0; i < cv->jobs.size(); i++) { if (!cv->jobs[i]->isLive()) continue; Lua::PushDFObject(L, cv->jobs[i]->actual_job); lua_rawseti(L, -2, ++j); + + if (cv->jobs[i]->want_resumed) { + want_resumed = true; + resumed = resumed || cv->jobs[i]->isActuallyResumed(); + } } lua_setfield(L, ctable, "jobs"); + + if (want_resumed && !resumed) + Lua::SetField(L, true, ctable, "is_delayed"); } static int listConstraints(lua_State *L) { + lua_settop(L, 2); auto job = Lua::CheckDFObject(L, 1); + bool with_history = lua_toboolean(L, 2); lua_pushnil(L); @@ -1467,6 +1500,13 @@ static int listConstraints(lua_State *L) for (size_t i = 0; i < vec.size(); i++) { push_constraint(L, vec[i]); + + if (with_history) + { + push_count_history(L, vec[i]); + lua_setfield(L, -2, "history"); + } + lua_rawseti(L, -2, i+1); } @@ -1525,23 +1565,7 @@ static int getCountHistory(lua_State *L) ItemConstraint *icv = get_constraint(out, token, NULL, false); if (icv) - { - size_t hsize = icv->history_size(); - - lua_createtable(L, hsize, 0); - - for (int i = hsize-1; i >= 0; i--) - { - lua_createtable(L, 0, 4); - - Lua::SetField(L, icv->history_amount(i), -1, "cur_amount"); - Lua::SetField(L, icv->history_count(i), -1, "cur_count"); - Lua::SetField(L, icv->history_inuse_amount(i), -1, "cur_in_use_amount"); - Lua::SetField(L, icv->history_inuse_count(i), -1, "cur_in_use_count"); - - lua_rawseti(L, -2, hsize-i); // reverse order - } - } + push_count_history(L, icv); else lua_pushnil(L); From 0bfe006016d76206c9a05f4c8c0d5aede3dd748e Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 30 Nov 2012 19:10:17 +0400 Subject: [PATCH 35/35] Try to reimplement the inventory monitor by falconne in lua. For no other reason than to provide a complete example of lua interface for a native plugin :) TODO: paint the graph in the right pane. --- Lua API.rst | 11 + library/lua/gui.lua | 10 +- library/lua/gui/widgets.lua | 41 +++- scripts/gui/workflow.lua | 410 +++++++++++++++++++++++++++++++++--- 4 files changed, 430 insertions(+), 42 deletions(-) diff --git a/Lua API.rst b/Lua API.rst index d42a348e4..714a41bfb 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -2710,6 +2710,16 @@ containing newlines, or a table with the following possible fields: Specifies a pen to paint as one tile before the main part of the token. +* ``token.width = ...`` + + If specified either as a value or a callback, the text field is padded + or truncated to the specified number. + +* ``token.pad_char = '?'`` + + If specified together with ``width``, the padding area is filled with + this character instead of just being skipped over. + * ``token.key = '...'`` Specifies the keycode associated with the token. The string description @@ -2842,6 +2852,7 @@ In addition to passing through all attributes supported by List, it supports: :edit_pen: If specified, used instead of ``cursor_pen`` for the edit field. +:edit_below: If true, the edit field is placed below the list instead of above. :not_found_label: Specifies the text of the label shown when no items match the filter. The list choices may include the following attributes: diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 2145cfad1..99bf9263c 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -112,10 +112,14 @@ function inset_frame(rect, inset, gap) return mkdims_xy(rect.x1+l+gap, rect.y1+t+gap, rect.x2-r-gap, rect.y2-b-gap) end -function compute_frame_body(wavail, havail, spec, inset, gap) +function compute_frame_body(wavail, havail, spec, inset, gap, inner_frame) gap = gap or 0 local l,t,r,b = parse_inset(inset) - local rect = compute_frame_rect(wavail, havail, spec, gap*2+l+r, gap*2+t+b) + local xgap,ygap = 0,0 + if inner_frame then + xgap,ygap = gap*2+l+r, gap*2+t+b + end + local rect = compute_frame_rect(wavail, havail, spec, xgap, ygap) local body = mkdims_xy(rect.x1+l+gap, rect.y1+t+gap, rect.x2-r-gap, rect.y2-b-gap) return rect, body end @@ -623,7 +627,7 @@ end function FramedScreen:computeFrame(parent_rect) local sw, sh = parent_rect.width, parent_rect.height local fw, fh = self:getWantedFrameSize(parent_rect) - return compute_frame_body(sw, sh, { w = fw, h = fh }, self.frame_inset, 1) + return compute_frame_body(sw, sh, { w = fw, h = fh }, self.frame_inset, 1, true) end function FramedScreen:onRenderFrame(dc, rect) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 145300c59..ebbffbbbd 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -60,6 +60,7 @@ Panel = defclass(Panel, Widget) Panel.ATTRS { on_render = DEFAULT_NIL, + on_layout = DEFAULT_NIL, } function Panel:init(args) @@ -70,6 +71,10 @@ function Panel:onRenderBody(dc) if self.on_render then self.on_render(dc) end end +function Panel:postComputeFrame(body) + if self.on_layout then self.on_layout(body) end +end + ----------- -- Pages -- ----------- @@ -242,7 +247,7 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) end if token.text or token.key then - local text = getval(token.text) or '' + local text = ''..(getval(token.text) or '') local keypen if dc then @@ -256,7 +261,23 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) end end - x = x + #text + local width = getval(token.width) + local padstr + if width then + x = x + width + if #text > width then + text = string.sub(text,1,width) + else + if token.pad_char then + padstr = string.rep(token.pad_char,width-#text) + end + if dc and token.rjustify then + if padstr then dc:string(padstr) else dc:advance(width-#text) end + end + end + else + x = x + #text + end if token.key then local keystr = gui.getKeyDisplay(token.key) @@ -281,6 +302,10 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) dc:string(text) end end + + if width and dc and not token.rjustify then + if padstr then dc:string(padstr) else dc:advance(width-#text) end + end end token.x2 = x @@ -591,10 +616,14 @@ end FilteredList = defclass(FilteredList, Widget) +FilteredList.ATTRS { + edit_below = false, +} + function FilteredList:init(info) self.edit = EditField{ text_pen = info.edit_pen or info.cursor_pen, - frame = { l = info.icon_width, t = 0 }, + frame = { l = info.icon_width, t = 0, h = 1 }, on_change = self:callback('onFilterChange'), on_char = self:callback('onFilterChar'), } @@ -608,6 +637,10 @@ function FilteredList:init(info) scroll_keys = info.scroll_keys, icon_width = info.icon_width, } + if self.edit_below then + self.edit.frame = { l = info.icon_width, b = 0, h = 1 } + self.list.frame = { t = 0, b = 2 } + end if info.on_select then self.list.on_select = function() return info.on_select(self:getSelected()) @@ -627,7 +660,7 @@ function FilteredList:init(info) visible = false, text = info.not_found_label or 'No matches', text_pen = COLOR_LIGHTRED, - frame = { l = info.icon_width, t = 2 }, + frame = { l = info.icon_width, t = self.list.frame.t }, } self:addviews{ self.edit, self.list, self.not_found } self:setChoices(info.choices, info.selected) diff --git a/scripts/gui/workflow.lua b/scripts/gui/workflow.lua index a387e64b9..9a45f6554 100644 --- a/scripts/gui/workflow.lua +++ b/scripts/gui/workflow.lua @@ -66,20 +66,64 @@ function is_caste_mat(iobj) end function describe_material(iobj) - local matline = 'any material' + local matflags = utils.list_bitfield_flags(iobj.mat_mask) + if #matflags > 0 then + matflags = 'any '..table.concat(matflags, '/') + else + matflags = nil + end + if is_caste_mat(iobj) then - matline = 'no material' + return 'no material' elseif (iobj.mat_type or -1) >= 0 then local info = dfhack.matinfo.decode(iobj.mat_type, iobj.mat_index) + local matline if info then matline = info:toString() else matline = iobj.mat_type..':'..iobj.mat_index end + return matline, matflags + else + return matflags or 'any material' + end +end + +function current_stock(iobj) + if iobj.goal_by_count then + return iobj.cur_count + else + return iobj.cur_amount end - return matline end +function if_by_count(iobj,bc,ba) + if iobj.goal_by_count then + return bc + else + return ba + end +end + +function compute_trend(history,field) + local count = #history + if count == 0 then + return 0 + end + local sumX,sumY,sumXY,sumXX = 0,0,0,0 + for i,v in ipairs(history) do + sumX = sumX + i + sumY = sumY + v[field] + sumXY = sumXY + i*v[field] + sumXX = sumXX + i*i + end + return (count * sumXY - sumX * sumY) / (count * sumXX - sumX * sumX) +end + +------------------------ +-- RANGE EDITOR GROUP -- +------------------------ + local null_cons = { goal_value = 0, goal_gap = 0, goal_by_count = false } RangeEditor = defclass(RangeEditor, widgets.Label) @@ -162,6 +206,10 @@ function RangeEditor:onIncRange(field, delta) self.save_cb(cons) end +--------------------------- +-- NEW CONSTRAINT DIALOG -- +--------------------------- + NewConstraint = defclass(NewConstraint, gui.FramedScreen) NewConstraint.focus_path = 'workflow/new' @@ -177,7 +225,7 @@ NewConstraint.ATTRS { } function NewConstraint:init(args) - self.constraint = args.constraint or {} + self.constraint = args.constraint or { item_type = -1 } rawset_default(self.constraint, { goal_value = 10, goal_gap = 5, goal_by_count = false }) local matlist = {} @@ -202,8 +250,16 @@ function NewConstraint:init(args) frame = { l = 1, t = 2, w = 26 }, text = { 'Type: ', - { pen = COLOR_LIGHTCYAN, - text = function() return describe_item_type(self.constraint) end }, + { pen = function() + if self:isValid() then return COLOR_LIGHTCYAN else return COLOR_LIGHTRED end + end, + text = function() + if self:isValid() then + return describe_item_type(self.constraint) + else + return 'item not set' + end + end }, NEWLINE, ' ', { key = 'CUSTOM_T', text = ': Select, ', on_activate = self:callback('chooseType') }, @@ -277,6 +333,7 @@ function NewConstraint:init(args) { key = 'LEAVESCREEN', text = ': Cancel, ', on_activate = self:callback('dismiss') }, { key = 'MENU_CONFIRM', key_sep = ': ', + enabled = self:callback('isValid'), text = function() if self.is_existing then return 'Update' else return 'Create new' end end, @@ -295,9 +352,17 @@ function NewConstraint:postinit() self:onChange() end +function NewConstraint:isValid() + return self.constraint.item_type >= 0 +end + function NewConstraint:onChange() local token = workflow.constraintToToken(self.constraint) - local out = workflow.findConstraint(token) + local out + + if self:isValid() then + out = workflow.findConstraint(token) + end if out then self.constraint = out @@ -390,6 +455,288 @@ function NewConstraint:onRangeChange() cons.goal_gap = math.max(1, math.min(cons.goal_gap, cons.goal_value-1)) end +------------------------------ +-- GLOBAL CONSTRAINT SCREEN -- +------------------------------ + +ConstraintList = defclass(ConstraintList, gui.FramedScreen) + +ConstraintList.focus_path = 'workflow/list' + +ConstraintList.ATTRS { + frame_title = 'Workflow Status', + frame_inset = 0, + frame_background = COLOR_BLACK, + frame_style = gui.BOUNDARY_FRAME, +} + +function ConstraintList:init(args) + local fwidth_cb = self:cb_getfield('fwidth') + + self.fwidth = 20 + self.sort_by_severity = false + + self:addviews{ + widgets.Panel{ + frame = { w = 31, r = 0, h = 6, t = 0 }, + frame_inset = 1, + subviews = { + widgets.Label{ + frame = { l = 0, t = 0 }, + enabled = self:callback('isAnySelected'), + text = { + { text = function() + local cur = self:getCurConstraint() + if cur then + return string.format( + 'Currently %d (%d in use)', + current_stock(cur), + if_by_count(cur, cur.cur_in_use_count, cur.cur_in_use_amount) + ) + else + return 'No constraint selected' + end + end } + } + }, + RangeEditor{ + frame = { l = 0, t = 2 }, + enabled = self:callback('isAnySelected'), + get_cb = self:callback('getCurConstraint'), + save_cb = self:callback('saveConstraint'), + }, + } + }, + widgets.Widget{ + active = false, + frame = { w = 1, r = 31 }, + frame_background = gui.BOUNDARY_FRAME.frame_pen, + }, + widgets.Widget{ + active = false, + frame = { w = 31, r = 0, h = 1, t = 6 }, + frame_background = gui.BOUNDARY_FRAME.frame_pen, + }, + widgets.Panel{ + frame = { l = 0, r = 32 }, + frame_inset = 1, + on_layout = function(body) + self.fwidth = body.width - (12+1+1+7+1+1+1+7) + end, + subviews = { + widgets.Label{ + frame = { l = 0, t = 0 }, + text_pen = COLOR_CYAN, + text = { + { text = 'Item', width = 12 }, ' ', + { text = 'Material etc', width = fwidth_cb }, ' ', + { text = 'Stock / Limit' }, + } + }, + widgets.FilteredList{ + view_id = 'list', + frame = { t = 2, b = 2 }, + edit_below = true, + not_found_label = 'No matching constraints', + edit_pen = COLOR_LIGHTCYAN, + text_pen = { fg = COLOR_GREY, bg = COLOR_BLACK }, + cursor_pen = { fg = COLOR_WHITE, bg = COLOR_GREEN }, + }, + widgets.Label{ + frame = { b = 0, h = 1 }, + text = { + { key = 'CUSTOM_SHIFT_A', text = ': Add', + on_activate = self:callback('onNewConstraint') }, ', ', + { key = 'CUSTOM_SHIFT_X', text = ': Delete', + on_activate = self:callback('onDeleteConstraint') }, ', ', + { key = 'CUSTOM_SHIFT_O', text = ': Severity Order', + on_activate = self:callback('onSwitchSort'), + pen = function() + if self.sort_by_severity then + return COLOR_LIGHTCYAN + else + return COLOR_WHITE + end + end }, ', ', + { key = 'CUSTOM_SHIFT_S', text = ': Search', + on_activate = function() + self.subviews.list.edit.active = not self.subviews.list.edit.active + end, + pen = function() + if self.subviews.list.edit.active then + return COLOR_LIGHTCYAN + else + return COLOR_WHITE + end + end } + } + } + } + }, + } + + self.subviews.list.edit.active = false + + self:initListChoices() +end + +function stock_trend_color(cons) + local stock = current_stock(cons) + if stock >= cons.goal_value - cons.goal_gap then + return COLOR_LIGHTGREEN, 0 + elseif stock <= cons.goal_gap then + return COLOR_LIGHTRED, 4 + elseif stock >= cons.goal_value - 2*cons.goal_gap then + return COLOR_GREEN, 1 + elseif stock <= 2*cons.goal_gap then + return COLOR_RED, 3 + else + local trend = if_by_count(cons, cons.trend_count, cons.trend_amount) + if trend > 0.3 then + return COLOR_GREEN, 1 + elseif trend < -0.3 then + return COLOR_RED, 3 + else + return COLOR_GREY, 2 + end + end +end + +function ConstraintList:initListChoices(clist, sel_token) + clist = clist or workflow.listConstraints(nil, true) + + local fwidth_cb = self:cb_getfield('fwidth') + local choices = {} + + for i,cons in ipairs(clist) do + cons.trend_count = compute_trend(cons.history, 'cur_count') + cons.trend_amount = compute_trend(cons.history, 'cur_amount') + + local itemstr = describe_item_type(cons) + local matstr,matflagstr = describe_material(cons) + if matflagstr then + matstr = matflagstr .. ' ' .. matstr + end + + if cons.min_quality > 0 or cons.is_local then + local lst = {} + if cons.is_local then + table.insert(lst, 'local') + end + if cons.min_quality > 0 then + table.insert(lst, string.lower(df.item_quality[cons.min_quality])) + end + matstr = matstr .. ' ('..table.concat(lst,',')..')' + end + + local goal_color = COLOR_GREY + if #cons.jobs == 0 then + goal_color = COLOR_RED + elseif cons.is_delayed then + goal_color = COLOR_YELLOW + end + + table.insert(choices, { + text = { + { text = itemstr, width = 12, pad_char = ' ' }, ' ', + { text = matstr, width = fwidth_cb, pad_char = ' ' }, ' ', + { text = curry(current_stock,cons), width = 7, rjustify = true, + pen = function() return { fg = stock_trend_color(cons) } end }, + { text = curry(if_by_count,cons,'S','I'), gap = 1, + pen = { fg = COLOR_GREY } }, + { text = function() return cons.goal_value end, gap = 1, + pen = { fg = goal_color } } + }, + severity = select(2, stock_trend_color(cons)), + search_key = itemstr .. ' | ' .. matstr, + token = cons.token, + obj = cons + }) + end + + self:setChoices(choices, sel_token) +end + +function ConstraintList:isAnySelected() + return self.subviews.list:getSelected() ~= nil +end + +function ConstraintList:getCurConstraint() + local selidx,selobj = self.subviews.list:getSelected() + if selobj then return selobj.obj end +end + +function ConstraintList:onSwitchSort() + self.sort_by_severity = not self.sort_by_severity + self:setChoices(self.subviews.list:getChoices()) +end + +function ConstraintList:setChoices(choices, sel_token) + if self.sort_by_severity then + table.sort(choices, function(a,b) + return a.severity > b.severity + or (a.severity == b.severity and + current_stock(a.obj)/a.obj.goal_value < current_stock(b.obj)/b.obj.goal_value) + end) + else + table.sort(choices, function(a,b) return a.search_key < b.search_key end) + end + + local selidx = nil + if sel_token then + selidx = utils.linear_index(choices, sel_token, 'token') + end + + local list = self.subviews.list + local filter = list:getFilter() + + list:setChoices(choices, selidx) + + if filter ~= '' then + list:setFilter(filter, selidx) + + if selidx and list:getSelected() ~= selidx then + list:setFilter('', selidx) + end + end +end + +function ConstraintList:onInput(keys) + if keys.LEAVESCREEN then + self:dismiss() + else + ConstraintList.super.onInput(self, keys) + end +end + +function ConstraintList:onNewConstraint() + NewConstraint{ + on_submit = self:callback('saveConstraint') + }:show() +end + +function ConstraintList:saveConstraint(cons) + local out = workflow.setConstraint(cons.token, cons.goal_by_count, cons.goal_value, cons.goal_gap) + self:initListChoices(nil, out.token) +end + +function ConstraintList:onDeleteConstraint() + local cons = self:getCurConstraint() + dlg.showYesNoPrompt( + 'Delete Constraint', + 'Really delete the current constraint?', + COLOR_YELLOW, + function() + workflow.deleteConstraint(cons.token) + self:initListChoices() + end + ) +end + +------------------------------- +-- WORKSHOP JOB INFO OVERLAY -- +------------------------------- + JobConstraints = defclass(JobConstraints, guidm.MenuOverlay) JobConstraints.focus_path = 'workflow/job' @@ -480,24 +827,12 @@ function JobConstraints:initListChoices(clist, sel_token) end itemstr = itemstr .. ' ('..table.concat(lst,',')..')' end - local matstr = describe_material(cons) - local matflagstr = '' - local matflags = utils.list_bitfield_flags(cons.mat_mask) - if #matflags > 0 then - matflags[1] = 'any '..matflags[1] - if matstr == 'any material' then - matstr = table.concat(matflags, ', ') - matflags = {} - end - end - if #matflags > 0 then - matflagstr = table.concat(matflags, ', ') - end + local matstr,matflagstr = describe_material(cons) table.insert(choices, { text = { goal, ' ', { text = '(now '..curval..')', pen = order_pen }, NEWLINE, - ' ', itemstr, NEWLINE, ' ', matstr, NEWLINE, ' ', matflagstr + ' ', itemstr, NEWLINE, ' ', matstr, NEWLINE, ' ', (matflagstr or '') }, token = cons.token, obj = cons @@ -593,20 +928,25 @@ function JobConstraints:onInput(keys) end end -if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some/Workshop/Job') then - qerror("This script requires a workshop job selected in the 'q' mode") -end +local args = {...} -local job = dfhack.gui.getSelectedJob() +if args[1] == 'list' then + check_enabled(function() ConstraintList{}:show() end) +else + if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some/Workshop/Job') then + qerror("This script requires a workshop job selected in the 'q' mode") + end -check_enabled(function() - check_repeat(job, function() - local clist = workflow.listConstraints(job) - if not clist then - dlg.showMessage('Not Supported', 'This type of job is not supported by workflow.', COLOR_LIGHTRED) - return - end - JobConstraints{ job = job, clist = clist }:show() - end) -end) + local job = dfhack.gui.getSelectedJob() + check_enabled(function() + check_repeat(job, function() + local clist = workflow.listConstraints(job) + if not clist then + dlg.showMessage('Not Supported', 'This type of job is not supported by workflow.', COLOR_LIGHTRED) + return + end + JobConstraints{ job = job, clist = clist }:show() + end) + end) +end