From ad7de34d3f1247e87ad46c2e373099c948ce7145 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 12:15:01 -0700 Subject: [PATCH 1/9] add clickable overlay to title screen --- plugins/CMakeLists.txt | 1 + plugins/overlay.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 plugins/overlay.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 49e704b75..dc341b39d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -144,6 +144,7 @@ if(BUILD_SUPPORTED) dfhack_plugin(mousequery mousequery.cpp) dfhack_plugin(nestboxes nestboxes.cpp) dfhack_plugin(orders orders.cpp LINK_LIBRARIES jsoncpp_static) + dfhack_plugin(overlay overlay.cpp) dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua) dfhack_plugin(petcapRemover petcapRemover.cpp) dfhack_plugin(plants plants.cpp) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp new file mode 100644 index 000000000..42241aec6 --- /dev/null +++ b/plugins/overlay.cpp @@ -0,0 +1,80 @@ +#include "df/viewscreen_titlest.h" + +#include "modules/Gui.h" + +#include "PluginManager.h" +#include "VTableInterpose.h" +#include "uicommon.h" + +using namespace DFHack; + +DFHACK_PLUGIN("overlay"); +DFHACK_PLUGIN_IS_ENABLED(is_enabled); +REQUIRE_GLOBAL(enabler); +REQUIRE_GLOBAL(gps); + +static const std::string button_text = "[ DFHack Launcher ]"; +static bool clicked = false; + +static bool handle_click() { + int32_t x, y; + if (!enabler->tracking_on || !enabler->mouse_lbut || clicked || + !Gui::getMousePos(x, y)) + return false; + if (y == gps->dimy - 1 && x >= 1 && (size_t)x <= button_text.size()) { + clicked = true; + Core::getInstance().setHotkeyCmd("gui/launcher"); + return true; + } + return false; +} + +static void draw_widgets() { + int x = 1; + int y = gps->dimy - 1; + OutputString(COLOR_GREEN, x, y, button_text); +} + +struct title_hook : df::viewscreen_titlest { + typedef df::viewscreen_titlest interpose_base; + + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { + if (!handle_click()) + INTERPOSE_NEXT(feed)(input); + } + DEFINE_VMETHOD_INTERPOSE(void, render, ()) { + INTERPOSE_NEXT(render)(); + draw_widgets(); + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(title_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render); + +DFhackCExport command_result plugin_onstatechange(color_ostream &, + state_change_event evt) { + if (evt == SC_VIEWSCREEN_CHANGED) { + clicked = false; + } + return CR_OK; +} + +DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { + if (is_enabled == enable) + return CR_OK; + if (enable != is_enabled) { + if (!INTERPOSE_HOOK(title_hook, feed).apply(enable) || + !INTERPOSE_HOOK(title_hook, render).apply(enable)) + return CR_FAILURE; + + is_enabled = enable; + } + return CR_OK; +} + +DFhackCExport command_result plugin_init(color_ostream &out, std::vector &) { + return plugin_enable(out, true); +} + +DFhackCExport command_result plugin_shutdown(color_ostream &out) { + return plugin_enable(out, false); +} From 8ab2f063df3a32b475996ef5e0e8bc10c3e70463 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 13:38:05 -0700 Subject: [PATCH 2/9] hook remaining df screens --- plugins/overlay.cpp | 267 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 261 insertions(+), 6 deletions(-) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index 42241aec6..9a5c625ab 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -1,4 +1,87 @@ +#include "df/viewscreen_adopt_regionst.h" +#include "df/viewscreen_adventure_logst.h" +#include "df/viewscreen_announcelistst.h" +#include "df/viewscreen_assign_display_itemst.h" +#include "df/viewscreen_barterst.h" +#include "df/viewscreen_buildinglistst.h" +#include "df/viewscreen_buildingst.h" +#include "df/viewscreen_choose_start_sitest.h" +#include "df/viewscreen_civlistst.h" +#include "df/viewscreen_counterintelligencest.h" +#include "df/viewscreen_createquotast.h" +#include "df/viewscreen_customize_unitst.h" +#include "df/viewscreen_dungeonmodest.h" +#include "df/viewscreen_dungeon_monsterstatusst.h" +#include "df/viewscreen_dungeon_wrestlest.h" +#include "df/viewscreen_dwarfmodest.h" +#include "df/viewscreen_entityst.h" +#include "df/viewscreen_export_graphical_mapst.h" +#include "df/viewscreen_export_regionst.h" +#include "df/viewscreen_game_cleanerst.h" +#include "df/viewscreen_image_creator_mode.h" +#include "df/viewscreen_image_creatorst.h" +#include "df/viewscreen_itemst.h" +#include "df/viewscreen_joblistst.h" +#include "df/viewscreen_jobmanagementst.h" +#include "df/viewscreen_jobst.h" +#include "df/viewscreen_justicest.h" +#include "df/viewscreen_kitchenpref_page.h" +#include "df/viewscreen_kitchenprefst.h" +#include "df/viewscreen_layer_arena_creaturest.h" +#include "df/viewscreen_layer_assigntradest.h" +#include "df/viewscreen_layer_choose_language_namest.h" +#include "df/viewscreen_layer_currencyst.h" +#include "df/viewscreen_layer_export_play_mapst.h" +#include "df/viewscreen_layer.h" +#include "df/viewscreen_layer_militaryst.h" +#include "df/viewscreen_layer_musicsoundst.h" +#include "df/viewscreen_layer_noblelistst.h" +#include "df/viewscreen_layer_overall_healthst.h" +#include "df/viewscreen_layer_reactionst.h" +#include "df/viewscreen_layer_squad_schedulest.h" +#include "df/viewscreen_layer_stockpilest.h" +#include "df/viewscreen_layer_stone_restrictionst.h" +#include "df/viewscreen_layer_unit_actionst.h" +#include "df/viewscreen_layer_unit_healthst.h" +#include "df/viewscreen_layer_unit_relationshipst.h" +#include "df/viewscreen_layer_world_gen_param_presetst.h" +#include "df/viewscreen_layer_world_gen_paramst.h" +#include "df/viewscreen_legendsst.h" +#include "df/viewscreen_loadgamest.h" +#include "df/viewscreen_locationsst.h" +#include "df/viewscreen_meetingst.h" +#include "df/viewscreen_movieplayerst.h" +#include "df/viewscreen_new_regionst.h" +#include "df/viewscreen_noblest.h" +#include "df/viewscreen_optionst.h" +#include "df/viewscreen_overallstatusst.h" +#include "df/viewscreen_petitionsst.h" +#include "df/viewscreen_petst.h" +#include "df/viewscreen_pricest.h" +#include "df/viewscreen_reportlistst.h" +#include "df/viewscreen_requestagreementst.h" +#include "df/viewscreen_savegamest.h" +#include "df/viewscreen_selectitemst.h" +#include "df/viewscreen_setupadventurest.h" +#include "df/viewscreen_setupdwarfgamest.h" +#include "df/viewscreen_storesst.h" +#include "df/viewscreen_textviewerst.h" #include "df/viewscreen_titlest.h" +#include "df/viewscreen_topicmeeting_fill_land_holder_positionsst.h" +#include "df/viewscreen_topicmeetingst.h" +#include "df/viewscreen_topicmeeting_takerequestsst.h" +#include "df/viewscreen_tradeagreementst.h" +#include "df/viewscreen_tradegoodsst.h" +#include "df/viewscreen_tradelistst.h" +#include "df/viewscreen_treasurelistst.h" +#include "df/viewscreen_unitlist_page.h" +#include "df/viewscreen_unitlistst.h" +#include "df/viewscreen_unitst.h" +#include "df/viewscreen_update_regionst.h" +#include "df/viewscreen_wagesst.h" +#include "df/viewscreen_workquota_conditionst.h" +#include "df/viewscreen_workquota_detailsst.h" +#include "df/viewscreen_workshop_profilest.h" #include "modules/Gui.h" @@ -35,8 +118,9 @@ static void draw_widgets() { OutputString(COLOR_GREEN, x, y, button_text); } -struct title_hook : df::viewscreen_titlest { - typedef df::viewscreen_titlest interpose_base; +template +struct viewscreen_overlay : T { + typedef T interpose_base; DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { if (!handle_click()) @@ -47,8 +131,94 @@ struct title_hook : df::viewscreen_titlest { draw_widgets(); } }; -IMPLEMENT_VMETHOD_INTERPOSE(title_hook, feed); -IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render); + +#define IMPLEMENT_HOOKS(screen) \ + typedef viewscreen_overlay screen##_overlay; \ + template<> IMPLEMENT_VMETHOD_INTERPOSE(screen##_overlay, feed); \ + template<> IMPLEMENT_VMETHOD_INTERPOSE(screen##_overlay, render); + +IMPLEMENT_HOOKS(adopt_region) +IMPLEMENT_HOOKS(adventure_log) +IMPLEMENT_HOOKS(announcelist) +IMPLEMENT_HOOKS(assign_display_item) +IMPLEMENT_HOOKS(barter) +IMPLEMENT_HOOKS(buildinglist) +IMPLEMENT_HOOKS(building) +IMPLEMENT_HOOKS(choose_start_site) +IMPLEMENT_HOOKS(civlist) +IMPLEMENT_HOOKS(counterintelligence) +IMPLEMENT_HOOKS(createquota) +IMPLEMENT_HOOKS(customize_unit) +IMPLEMENT_HOOKS(dungeonmode) +IMPLEMENT_HOOKS(dungeon_monsterstatus) +IMPLEMENT_HOOKS(dungeon_wrestle) +IMPLEMENT_HOOKS(dwarfmode) +IMPLEMENT_HOOKS(entity) +IMPLEMENT_HOOKS(export_graphical_map) +IMPLEMENT_HOOKS(export_region) +IMPLEMENT_HOOKS(game_cleaner) +IMPLEMENT_HOOKS(image_creator) +IMPLEMENT_HOOKS(item) +IMPLEMENT_HOOKS(joblist) +IMPLEMENT_HOOKS(jobmanagement) +IMPLEMENT_HOOKS(job) +IMPLEMENT_HOOKS(justice) +IMPLEMENT_HOOKS(kitchenpref) +IMPLEMENT_HOOKS(layer_arena_creature) +IMPLEMENT_HOOKS(layer_assigntrade) +IMPLEMENT_HOOKS(layer_choose_language_name) +IMPLEMENT_HOOKS(layer_currency) +IMPLEMENT_HOOKS(layer_export_play_map) +IMPLEMENT_HOOKS(layer_military) +IMPLEMENT_HOOKS(layer_musicsound) +IMPLEMENT_HOOKS(layer_noblelist) +IMPLEMENT_HOOKS(layer_overall_health) +IMPLEMENT_HOOKS(layer_reaction) +IMPLEMENT_HOOKS(layer_squad_schedule) +IMPLEMENT_HOOKS(layer_stockpile) +IMPLEMENT_HOOKS(layer_stone_restriction) +IMPLEMENT_HOOKS(layer_unit_action) +IMPLEMENT_HOOKS(layer_unit_health) +IMPLEMENT_HOOKS(layer_unit_relationship) +IMPLEMENT_HOOKS(layer_world_gen_param_preset) +IMPLEMENT_HOOKS(layer_world_gen_param) +IMPLEMENT_HOOKS(legends) +IMPLEMENT_HOOKS(loadgame) +IMPLEMENT_HOOKS(locations) +IMPLEMENT_HOOKS(meeting) +IMPLEMENT_HOOKS(movieplayer) +IMPLEMENT_HOOKS(new_region) +IMPLEMENT_HOOKS(noble) +IMPLEMENT_HOOKS(option) +IMPLEMENT_HOOKS(overallstatus) +IMPLEMENT_HOOKS(petitions) +IMPLEMENT_HOOKS(pet) +IMPLEMENT_HOOKS(price) +IMPLEMENT_HOOKS(reportlist) +IMPLEMENT_HOOKS(requestagreement) +IMPLEMENT_HOOKS(savegame) +IMPLEMENT_HOOKS(selectitem) +IMPLEMENT_HOOKS(setupadventure) +IMPLEMENT_HOOKS(setupdwarfgame) +IMPLEMENT_HOOKS(stores) +IMPLEMENT_HOOKS(textviewer) +IMPLEMENT_HOOKS(title) +IMPLEMENT_HOOKS(topicmeeting_fill_land_holder_positions) +IMPLEMENT_HOOKS(topicmeeting) +IMPLEMENT_HOOKS(topicmeeting_takerequests) +IMPLEMENT_HOOKS(tradeagreement) +IMPLEMENT_HOOKS(tradegoods) +IMPLEMENT_HOOKS(tradelist) +IMPLEMENT_HOOKS(treasurelist) +IMPLEMENT_HOOKS(unitlist) +IMPLEMENT_HOOKS(unit) +IMPLEMENT_HOOKS(update_region) +IMPLEMENT_HOOKS(wages) +IMPLEMENT_HOOKS(workquota_condition) +IMPLEMENT_HOOKS(workquota_details) +IMPLEMENT_HOOKS(workshop_profile) + +#undef IMPLEMENT_HOOKS DFhackCExport command_result plugin_onstatechange(color_ostream &, state_change_event evt) { @@ -58,12 +228,95 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &, return CR_OK; } +#define INTERPOSE_HOOKS_FAILED(screen) \ + !INTERPOSE_HOOK(screen##_overlay, feed).apply(enable) || \ + !INTERPOSE_HOOK(screen##_overlay, render).apply(enable) + DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { if (is_enabled == enable) return CR_OK; + if (enable != is_enabled) { - if (!INTERPOSE_HOOK(title_hook, feed).apply(enable) || - !INTERPOSE_HOOK(title_hook, render).apply(enable)) + if (INTERPOSE_HOOKS_FAILED(adopt_region) || + INTERPOSE_HOOKS_FAILED(adventure_log) || + INTERPOSE_HOOKS_FAILED(announcelist) || + INTERPOSE_HOOKS_FAILED(assign_display_item) || + INTERPOSE_HOOKS_FAILED(barter) || + INTERPOSE_HOOKS_FAILED(buildinglist) || + INTERPOSE_HOOKS_FAILED(building) || + INTERPOSE_HOOKS_FAILED(choose_start_site) || + INTERPOSE_HOOKS_FAILED(civlist) || + INTERPOSE_HOOKS_FAILED(counterintelligence) || + INTERPOSE_HOOKS_FAILED(createquota) || + INTERPOSE_HOOKS_FAILED(customize_unit) || + INTERPOSE_HOOKS_FAILED(dungeonmode) || + INTERPOSE_HOOKS_FAILED(dungeon_monsterstatus) || + INTERPOSE_HOOKS_FAILED(dungeon_wrestle) || + INTERPOSE_HOOKS_FAILED(dwarfmode) || + INTERPOSE_HOOKS_FAILED(entity) || + INTERPOSE_HOOKS_FAILED(export_graphical_map) || + INTERPOSE_HOOKS_FAILED(export_region) || + INTERPOSE_HOOKS_FAILED(game_cleaner) || + INTERPOSE_HOOKS_FAILED(image_creator) || + INTERPOSE_HOOKS_FAILED(item) || + INTERPOSE_HOOKS_FAILED(joblist) || + INTERPOSE_HOOKS_FAILED(jobmanagement) || + INTERPOSE_HOOKS_FAILED(job) || + INTERPOSE_HOOKS_FAILED(justice) || + INTERPOSE_HOOKS_FAILED(kitchenpref) || + INTERPOSE_HOOKS_FAILED(layer_arena_creature) || + INTERPOSE_HOOKS_FAILED(layer_assigntrade) || + INTERPOSE_HOOKS_FAILED(layer_choose_language_name) || + INTERPOSE_HOOKS_FAILED(layer_currency) || + INTERPOSE_HOOKS_FAILED(layer_export_play_map) || + INTERPOSE_HOOKS_FAILED(layer_military) || + INTERPOSE_HOOKS_FAILED(layer_musicsound) || + INTERPOSE_HOOKS_FAILED(layer_noblelist) || + INTERPOSE_HOOKS_FAILED(layer_overall_health) || + INTERPOSE_HOOKS_FAILED(layer_reaction) || + INTERPOSE_HOOKS_FAILED(layer_squad_schedule) || + INTERPOSE_HOOKS_FAILED(layer_stockpile) || + INTERPOSE_HOOKS_FAILED(layer_stone_restriction) || + INTERPOSE_HOOKS_FAILED(layer_unit_action) || + INTERPOSE_HOOKS_FAILED(layer_unit_health) || + INTERPOSE_HOOKS_FAILED(layer_unit_relationship) || + INTERPOSE_HOOKS_FAILED(layer_world_gen_param_preset) || + INTERPOSE_HOOKS_FAILED(layer_world_gen_param) || + INTERPOSE_HOOKS_FAILED(legends) || + INTERPOSE_HOOKS_FAILED(loadgame) || + INTERPOSE_HOOKS_FAILED(locations) || + INTERPOSE_HOOKS_FAILED(meeting) || + INTERPOSE_HOOKS_FAILED(movieplayer) || + INTERPOSE_HOOKS_FAILED(new_region) || + INTERPOSE_HOOKS_FAILED(noble) || + INTERPOSE_HOOKS_FAILED(option) || + INTERPOSE_HOOKS_FAILED(overallstatus) || + INTERPOSE_HOOKS_FAILED(petitions) || + INTERPOSE_HOOKS_FAILED(pet) || + INTERPOSE_HOOKS_FAILED(price) || + INTERPOSE_HOOKS_FAILED(reportlist) || + INTERPOSE_HOOKS_FAILED(requestagreement) || + INTERPOSE_HOOKS_FAILED(savegame) || + INTERPOSE_HOOKS_FAILED(selectitem) || + INTERPOSE_HOOKS_FAILED(setupadventure) || + INTERPOSE_HOOKS_FAILED(setupdwarfgame) || + INTERPOSE_HOOKS_FAILED(stores) || + INTERPOSE_HOOKS_FAILED(textviewer) || + INTERPOSE_HOOKS_FAILED(title) || + INTERPOSE_HOOKS_FAILED(topicmeeting_fill_land_holder_positions) || + INTERPOSE_HOOKS_FAILED(topicmeeting) || + INTERPOSE_HOOKS_FAILED(topicmeeting_takerequests) || + INTERPOSE_HOOKS_FAILED(tradeagreement) || + INTERPOSE_HOOKS_FAILED(tradegoods) || + INTERPOSE_HOOKS_FAILED(tradelist) || + INTERPOSE_HOOKS_FAILED(treasurelist) || + INTERPOSE_HOOKS_FAILED(unitlist) || + INTERPOSE_HOOKS_FAILED(unit) || + INTERPOSE_HOOKS_FAILED(update_region) || + INTERPOSE_HOOKS_FAILED(wages) || + INTERPOSE_HOOKS_FAILED(workquota_condition) || + INTERPOSE_HOOKS_FAILED(workquota_details) || + INTERPOSE_HOOKS_FAILED(workshop_profile)) return CR_FAILURE; is_enabled = enable; @@ -71,6 +324,8 @@ DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { return CR_OK; } +#undef INTERPOSE_HOOKS_FAILED + DFhackCExport command_result plugin_init(color_ostream &out, std::vector &) { return plugin_enable(out, true); } From 089d2b6c33d89e3c05a74c5e5f8a5539a8c5356a Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 13:43:37 -0700 Subject: [PATCH 3/9] move dwarfmonitor's weather indicator to the right --- dfhack-config/dwarfmonitor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dfhack-config/dwarfmonitor.json b/dfhack-config/dwarfmonitor.json index 3fd365e74..007dad020 100644 --- a/dfhack-config/dwarfmonitor.json +++ b/dfhack-config/dwarfmonitor.json @@ -2,7 +2,7 @@ "widgets": [ { "type": "weather", - "x": 1, + "x": 22, "y": -1 }, { From 4800037ad36d3059c584ff523e4c9275616d416b Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 13:49:46 -0700 Subject: [PATCH 4/9] in dwarf mode, we must use lbut_down --- plugins/overlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index 9a5c625ab..c4bbfb95b 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -101,7 +101,7 @@ static bool clicked = false; static bool handle_click() { int32_t x, y; - if (!enabler->tracking_on || !enabler->mouse_lbut || clicked || + if (!enabler->tracking_on || !enabler->mouse_lbut_down || clicked || !Gui::getMousePos(x, y)) return false; if (y == gps->dimy - 1 && x >= 1 && (size_t)x <= button_text.size()) { From 301563d1e643fa6249c3d7c1708c221482df66d5 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 13:52:06 -0700 Subject: [PATCH 5/9] update changelog --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index f46b197ab..c3f8996c3 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## New Plugins - `autonestbox`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autonestbox start`` to ``enable autonestbox``. - `autobutcher`: split off from `zone` into its own plugin. Note that to enable, the command has changed from ``autobutcher start`` to ``enable autobutcher``. +- `overlay`: display a "DFHack" button in the lower left corner that you can click to start the new GUI command launcher. ## New Tweaks From b084171048657a4080bec4d0d67ab64ce88dfa11 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 14:01:29 -0700 Subject: [PATCH 6/9] add overlay docs --- docs/plugins/overlay.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 docs/plugins/overlay.rst diff --git a/docs/plugins/overlay.rst b/docs/plugins/overlay.rst new file mode 100644 index 000000000..9416fba31 --- /dev/null +++ b/docs/plugins/overlay.rst @@ -0,0 +1,20 @@ +overlay +======= + +.. dfhack-tool:: + :summary: Provide an on-screen clickable DFHack launcher button. + :tags: dfhack interface + +This tool places a small button in the lower left corner of the screen that you +can click to run DFHack commands with `gui/launcher`. + +If you would rather always run `gui/launcher` with the hotkeys, or just don't +want the DFHack button on-screen, just disable the plugin with +``disable overlay``. + +Usage +----- + +:: + + enable overlay From 3feca2ae58e6977326130f0bad82d9cc6f9252ee Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 16:19:21 -0700 Subject: [PATCH 7/9] make the overlay work with TWBT --- plugins/overlay.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index c4bbfb95b..386b4b532 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -1,3 +1,5 @@ +#include "df/renderer.h" + #include "df/viewscreen_adopt_regionst.h" #include "df/viewscreen_adventure_logst.h" #include "df/viewscreen_announcelistst.h" @@ -83,8 +85,7 @@ #include "df/viewscreen_workquota_detailsst.h" #include "df/viewscreen_workshop_profilest.h" -#include "modules/Gui.h" - +#include "Debug.h" #include "PluginManager.h" #include "VTableInterpose.h" #include "uicommon.h" @@ -96,14 +97,23 @@ DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(gps); +namespace DFHack { + DBG_DECLARE(overlay, log, DebugCategory::LINFO); +} + static const std::string button_text = "[ DFHack Launcher ]"; static bool clicked = false; static bool handle_click() { - int32_t x, y; - if (!enabler->tracking_on || !enabler->mouse_lbut_down || clicked || - !Gui::getMousePos(x, y)) + int32_t x = 0, y = 0; + if (!enabler->mouse_lbut_down || clicked || + !enabler->renderer->get_mouse_coords(&x, &y)) { + DEBUG(log).print( + "lbut_down=%s; clicked=%s; mouse_x=%d; mouse_y=%d\n", + enabler->mouse_lbut_down ? "true" : "false", + clicked ? "true" : "false", x, y); return false; + } if (y == gps->dimy - 1 && x >= 1 && (size_t)x <= button_text.size()) { clicked = true; Core::getInstance().setHotkeyCmd("gui/launcher"); From d0a5db2a0d4b4aed4e6d4dcee24bb92393729a22 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 20:59:02 -0700 Subject: [PATCH 8/9] set sentinel value used by TWBT --- library/include/modules/Renderer.h | 7 +++++++ library/modules/Renderer.cpp | 2 ++ plugins/overlay.cpp | 6 +++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/library/include/modules/Renderer.h b/library/include/modules/Renderer.h index 11abd7c1d..65a9694ab 100644 --- a/library/include/modules/Renderer.h +++ b/library/include/modules/Renderer.h @@ -5,6 +5,13 @@ #pragma once namespace DFHack { namespace Renderer { + // If the the 'x' parameter points to this value, then the 'y' parameter will + // be interpreted as a boolean flag for whether to return map coordinates (false) + // or text tile coordinates (true). Only TWBT implements this logic, and this + // sentinel value can be removed once DF provides an API for retrieving the + // two sets of coordinates. + DFHACK_EXPORT extern const int32_t GET_MOUSE_COORDS_SENTINEL; + struct DFHACK_EXPORT renderer_wrap : public df::renderer { void set_to_null(); void copy_from_parent(); diff --git a/library/modules/Renderer.cpp b/library/modules/Renderer.cpp index 474dc3656..b746a149c 100644 --- a/library/modules/Renderer.cpp +++ b/library/modules/Renderer.cpp @@ -9,6 +9,8 @@ using DFHack::Renderer::renderer_wrap; static renderer_wrap *original_renderer = NULL; +const int32_t Renderer::GET_MOUSE_COORDS_SENTINEL = 0xcd1aa471; + bool init() { if (!original_renderer) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index 386b4b532..b8c4e1fb4 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -1,5 +1,3 @@ -#include "df/renderer.h" - #include "df/viewscreen_adopt_regionst.h" #include "df/viewscreen_adventure_logst.h" #include "df/viewscreen_announcelistst.h" @@ -90,6 +88,8 @@ #include "VTableInterpose.h" #include "uicommon.h" +#include "modules/Renderer.h" + using namespace DFHack; DFHACK_PLUGIN("overlay"); @@ -105,7 +105,7 @@ static const std::string button_text = "[ DFHack Launcher ]"; static bool clicked = false; static bool handle_click() { - int32_t x = 0, y = 0; + int32_t x = Renderer::GET_MOUSE_COORDS_SENTINEL, y = (int32_t)true; if (!enabler->mouse_lbut_down || clicked || !enabler->renderer->get_mouse_coords(&x, &y)) { DEBUG(log).print( From dc5010c2e27ed1767c32893b8eccd86e6ebe3c47 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 16 Sep 2022 22:05:08 -0700 Subject: [PATCH 9/9] don't block text on the new region screen --- plugins/overlay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index b8c4e1fb4..1e66814a0 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -51,7 +51,6 @@ #include "df/viewscreen_locationsst.h" #include "df/viewscreen_meetingst.h" #include "df/viewscreen_movieplayerst.h" -#include "df/viewscreen_new_regionst.h" #include "df/viewscreen_noblest.h" #include "df/viewscreen_optionst.h" #include "df/viewscreen_overallstatusst.h" @@ -197,7 +196,6 @@ IMPLEMENT_HOOKS(loadgame) IMPLEMENT_HOOKS(locations) IMPLEMENT_HOOKS(meeting) IMPLEMENT_HOOKS(movieplayer) -IMPLEMENT_HOOKS(new_region) IMPLEMENT_HOOKS(noble) IMPLEMENT_HOOKS(option) IMPLEMENT_HOOKS(overallstatus) @@ -297,7 +295,6 @@ DFhackCExport command_result plugin_enable(color_ostream &, bool enable) { INTERPOSE_HOOKS_FAILED(locations) || INTERPOSE_HOOKS_FAILED(meeting) || INTERPOSE_HOOKS_FAILED(movieplayer) || - INTERPOSE_HOOKS_FAILED(new_region) || INTERPOSE_HOOKS_FAILED(noble) || INTERPOSE_HOOKS_FAILED(option) || INTERPOSE_HOOKS_FAILED(overallstatus) ||