From b0b601cf0fe55e6a4d93ee2f18db4392194e50dd Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 4 Jun 2022 11:59:04 -0700 Subject: [PATCH] Remove recenterViewscreen, update revealInDwarfmodeMap --- docs/Lua API.rst | 24 +++---- docs/changelog.txt | 4 +- library/LuaApi.cpp | 92 +++++++++++++----------- library/include/modules/Gui.h | 12 ++-- library/modules/Gui.cpp | 129 +++++++++++++--------------------- 5 files changed, 116 insertions(+), 145 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index efd963c03..803b84768 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1007,31 +1007,23 @@ Fortress mode * ``dfhack.gui.pauseRecenter(pos[,pause])`` ``dfhack.gui.pauseRecenter(x,y,z[,pause])`` - Same as ``resetDwarfmodeView``, but also recenter if ``x`` isn't ``-30000``. Respects + Same as ``resetDwarfmodeView``, but also recenter if position is valid. If ``pause`` is false, skip pausing. Respects ``RECENTER_INTERFACE_SHUTDOWN_MS`` in DF's ``init.txt`` (the delay before input is recognized when a recenter occurs.) -* ``dfhack.gui.recenterViewscreen(pos[,zoom])`` - ``dfhack.gui.recenterViewscreen(x,y,z[,zoom])`` - ``dfhack.gui.recenterViewscreen([zoom])`` +* ``dfhack.gui.revealInDwarfmodeMap(pos[,center])`` + ``dfhack.gui.revealInDwarfmodeMap(x,y,z[,center])`` - Recenter the view on a position using a specific zoom type. If no position is given, - recenter on ``df.global.cursor``. Zoom types are ``df.report_zoom_type`` - (see: `enum definition `_), - where ``df.report_zoom_type.Generic`` skips recentering and enforces valid view bounds (the same as x = -30000,) - ``df.report_zoom_type.Item`` brings the position onscreen without centering, and - ``df.report_zoom_type.Unit`` centers the screen on the position. Default zoom type is ``df.report_zoom_type.Item``. - -* ``dfhack.gui.revealInDwarfmodeMap(pos)`` - - Centers the view on the given position, which can be a ``df.coord`` instance - or a table assignable to a ``df.coord`` (see `lua-api-table-assignment`), + Centers the view on the given coordinates. If ``center`` is true, make sure the + position is in the exact center of the view, else just bring it on screen. + + ``pos`` can be a ``df.coord`` instance or a table assignable to a ``df.coord`` (see `lua-api-table-assignment`), e.g.:: {x = 5, y = 7, z = 11} getSelectedUnit().pos copyall(df.global.cursor) - Returns false if unsuccessful. + If the position is invalid, the function will simply ensure the current window position is clamped between valid values. * ``dfhack.gui.refreshSidebar()`` diff --git a/docs/changelog.txt b/docs/changelog.txt index 34b89d93e..fc184a35e 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -45,9 +45,11 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `dfhack-examples-guide`: refine food preparation orders and fix conditions for making jugs and pots in the ``basic`` manager orders ## Documentation +- ``dfhack.gui.revealInDwarfmodeMap``: document ``center`` bool for lua API ## API -- add functions reverse-engineered from announcement code: ``Gui::autoDFAnnouncement``, ``Gui::pauseRecenter``, ``Gui::recenterViewscreen`` +- add functions reverse-engineered from announcement code: ``Gui::autoDFAnnouncement``, ``Gui::pauseRecenter`` +- ``Gui::revealInDwarfmodeMap``: Now enforce valid view bounds when pos invalid, add variant accepting x, y, z ## Lua - ``widgets.HotkeyLabel``: the ``key_sep`` string is now configurable diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 5881e1b1f..b4e4fe3cd 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1457,26 +1457,6 @@ static const LuaWrapper::FunctionReg dfhack_module[] = { /***** Gui module *****/ -static int gui_getDwarfmodeViewDims(lua_State *state) -{ - auto dims = Gui::getDwarfmodeViewDims(); - lua_newtable(state); - Lua::TableInsert(state, "map_x1", dims.map_x1); - Lua::TableInsert(state, "map_x2", dims.map_x2); - Lua::TableInsert(state, "menu_x1", dims.menu_x1); - Lua::TableInsert(state, "menu_x2", dims.menu_x2); - Lua::TableInsert(state, "area_x1", dims.area_x1); - Lua::TableInsert(state, "area_x2", dims.area_x2); - Lua::TableInsert(state, "y1", dims.y1); - Lua::TableInsert(state, "y2", dims.y2); - Lua::TableInsert(state, "map_y1", dims.map_y1); - Lua::TableInsert(state, "map_y2", dims.map_y2); - Lua::TableInsert(state, "menu_on", dims.menu_on); - Lua::TableInsert(state, "area_on", dims.area_on); - Lua::TableInsert(state, "menu_forced", dims.menu_forced); - return 1; -} - static const LuaWrapper::FunctionReg dfhack_gui_module[] = { WRAPM(Gui, getCurViewscreen), WRAPM(Gui, getFocusString), @@ -1500,7 +1480,6 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = { WRAPM(Gui, showPopupAnnouncement), WRAPM(Gui, showAutoAnnouncement), WRAPM(Gui, resetDwarfmodeView), - WRAPM(Gui, revealInDwarfmodeMap), WRAPM(Gui, refreshSidebar), WRAPM(Gui, inRenameBuilding), WRAPM(Gui, getDepthAt), @@ -1520,7 +1499,7 @@ static int gui_autoDFAnnouncement(lua_State *state) else { df::coord pos; - int color = 0; //initialize these to prevent warning + int color = 0; // initialize these to prevent warning bool bright = false, is_sparring = false; df::unit *unit1 = NULL, *unit2 = NULL; @@ -1572,54 +1551,85 @@ static int gui_autoDFAnnouncement(lua_State *state) return 1; } +static int gui_getDwarfmodeViewDims(lua_State *state) +{ + auto dims = Gui::getDwarfmodeViewDims(); + lua_newtable(state); + Lua::TableInsert(state, "map_x1", dims.map_x1); + Lua::TableInsert(state, "map_x2", dims.map_x2); + Lua::TableInsert(state, "menu_x1", dims.menu_x1); + Lua::TableInsert(state, "menu_x2", dims.menu_x2); + Lua::TableInsert(state, "area_x1", dims.area_x1); + Lua::TableInsert(state, "area_x2", dims.area_x2); + Lua::TableInsert(state, "y1", dims.y1); + Lua::TableInsert(state, "y2", dims.y2); + Lua::TableInsert(state, "map_y1", dims.map_y1); + Lua::TableInsert(state, "map_y2", dims.map_y2); + Lua::TableInsert(state, "menu_on", dims.menu_on); + Lua::TableInsert(state, "area_on", dims.area_on); + Lua::TableInsert(state, "menu_forced", dims.menu_forced); + return 1; +} + static int gui_pauseRecenter(lua_State *state) { - if (lua_gettop(state) == 2) + bool rv; + df::coord p; + + switch (lua_gettop(state)) { - df::coord p; - Lua::CheckDFAssign(state, &p, 1); - Gui::pauseRecenter(p, lua_toboolean(state, 2)); + default: + case 4: + rv = Gui::pauseRecenter(CheckCoordXYZ(state, 1, false), lua_toboolean(state, 4)); + break; + case 3: + rv = Gui::pauseRecenter(CheckCoordXYZ(state, 1, false)); + break; + case 2: + Lua::CheckDFAssign(state, &p, 1); + rv = Gui::pauseRecenter(p, lua_toboolean(state, 2)); + break; + case 1: + Lua::CheckDFAssign(state, &p, 1); + rv = Gui::pauseRecenter(p); } - else - Gui::pauseRecenter(CheckCoordXYZ(state, 1, false), lua_toboolean(state, 4)); + lua_pushboolean(state, rv); return 1; } -static int gui_recenterViewscreen(lua_State *state) +static int gui_revealInDwarfmodeMap(lua_State *state) { + bool rv; df::coord p; + switch (lua_gettop(state)) { default: case 4: - Gui::recenterViewscreen(CheckCoordXYZ(state, 1, false), (df::report_zoom_type)lua_tointeger(state, 4)); + rv = Gui::revealInDwarfmodeMap(CheckCoordXYZ(state, 1, false), lua_toboolean(state, 4)); break; case 3: - Gui::recenterViewscreen(CheckCoordXYZ(state, 1, false)); + rv = Gui::revealInDwarfmodeMap(CheckCoordXYZ(state, 1, false)); break; case 2: Lua::CheckDFAssign(state, &p, 1); - Gui::recenterViewscreen(p, (df::report_zoom_type)lua_tointeger(state, 2)); + rv = Gui::revealInDwarfmodeMap(p, lua_toboolean(state, 2)); break; case 1: - if (lua_type(state, 1) == LUA_TNUMBER) - Gui::recenterViewscreen((df::report_zoom_type)lua_tointeger(state, 1)); - else - Gui::recenterViewscreen(CheckCoordXYZ(state, 1, true)); - break; - case 0: - Gui::recenterViewscreen(); + Lua::CheckDFAssign(state, &p, 1); + rv = Gui::revealInDwarfmodeMap(p); } + lua_pushboolean(state, rv); return 1; } static const luaL_Reg dfhack_gui_funcs[] = { { "autoDFAnnouncement", gui_autoDFAnnouncement }, - { "pauseRecenter", gui_pauseRecenter }, - { "recenterViewscreen", gui_recenterViewscreen }, { "getDwarfmodeViewDims", gui_getDwarfmodeViewDims }, + { "pauseRecenter", gui_pauseRecenter }, + { "revealInDwarfmodeMap", gui_revealInDwarfmodeMap }, { NULL, NULL } }; diff --git a/library/include/modules/Gui.h b/library/include/modules/Gui.h index bfe165179..c44d33f4e 100644 --- a/library/include/modules/Gui.h +++ b/library/include/modules/Gui.h @@ -138,13 +138,6 @@ namespace DFHack DFHACK_EXPORT df::coord getViewportPos(); DFHACK_EXPORT df::coord getCursorPos(); - // Recenter the viewscreen, based on DF code for announcements and scrolling - DFHACK_EXPORT void pauseRecenter(int32_t x, int32_t y, int32_t z, bool pause); - DFHACK_EXPORT inline void pauseRecenter(df::coord pos, bool pause) { pauseRecenter(pos.x, pos.y, pos.z, pause); } - DFHACK_EXPORT void recenterViewscreen(int32_t x, int32_t y, int32_t z, df::report_zoom_type zoom = df::enums::report_zoom_type::Item); - DFHACK_EXPORT inline void recenterViewscreen(df::coord pos, df::report_zoom_type zoom = df::enums::report_zoom_type::Item) { recenterViewscreen(pos.x, pos.y, pos.z, zoom); }; - DFHACK_EXPORT inline void recenterViewscreen(df::report_zoom_type zoom = df::enums::report_zoom_type::Item) { recenterViewscreen(getCursorPos(), zoom); }; - static const int AREA_MAP_WIDTH = 23; static const int MENU_WIDTH = 30; @@ -161,7 +154,10 @@ namespace DFHack DFHACK_EXPORT DwarfmodeDims getDwarfmodeViewDims(); DFHACK_EXPORT void resetDwarfmodeView(bool pause = false); - DFHACK_EXPORT bool revealInDwarfmodeMap(df::coord pos, bool center = false); + DFHACK_EXPORT bool revealInDwarfmodeMap(int32_t x, int32_t y, int32_t z, bool center = false); + DFHACK_EXPORT inline bool revealInDwarfmodeMap(df::coord pos, bool center = false) { return revealInDwarfmodeMap(pos.x, pos.y, pos.z, center); }; + DFHACK_EXPORT bool pauseRecenter(int32_t x, int32_t y, int32_t z, bool pause = true); + DFHACK_EXPORT inline bool pauseRecenter(df::coord pos, bool pause = true) { return pauseRecenter(pos.x, pos.y, pos.z, pause); }; DFHACK_EXPORT bool refreshSidebar(); DFHACK_EXPORT bool inRenameBuilding(); diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 16fd0057a..fa4535238 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -1387,7 +1387,7 @@ static bool parseReportString(std::vector *out, const std::string & if (str[i] == 'r') // "&r" adds a blank line { - word_wrap(out, parsed, line_length/*, WSMODE_TRIM_LEADING*/); + word_wrap(out, parsed, line_length, WSMODE_TRIM_LEADING); out->push_back(" "); // DF adds a line with a space for some reason parsed.clear(); } @@ -1401,7 +1401,7 @@ static bool parseReportString(std::vector *out, const std::string & while (++i < str.length()); if (parsed.length()) - word_wrap(out, parsed, line_length/*, WSMODE_TRIM_LEADING*/); + word_wrap(out, parsed, line_length, WSMODE_TRIM_LEADING); return true; } @@ -1921,65 +1921,6 @@ df::coord Gui::getCursorPos() return df::coord(cursor->x, cursor->y, cursor->z); } -void Gui::recenterViewscreen(int32_t x, int32_t y, int32_t z, df::report_zoom_type zoom) -{ // Reverse-engineered from DF announcement code, also used when scrolling - auto dims = getDwarfmodeViewDims(); - int32_t w = dims.map_x2 - dims.map_x1 + 1; - int32_t h = dims.map_y2 - dims.map_y1 + 1; - int32_t new_win_x, new_win_y, new_win_z; - getViewCoords(new_win_x, new_win_y, new_win_z); - - if (zoom != report_zoom_type::Generic && x != -30000) - { - if (zoom == report_zoom_type::Unit) - { - new_win_x = x - w / 2; - new_win_y = y - h / 2; - } - else // report_zoom_type::Item - { - if (new_win_x > (x - 5)) // equivalent to: "while (new_win_x > x - 5) new_win_x -= 10;" - new_win_x -= (new_win_x - (x - 5) - 1) / 10 * 10 + 10; - if (new_win_y > (y - 5)) - new_win_y -= (new_win_y - (y - 5) - 1) / 10 * 10 + 10; - if (new_win_x < (x + 5 - w)) - new_win_x += ((x + 5 - w) - new_win_x - 1) / 10 * 10 + 10; - if (new_win_y < (y + 5 - h)) - new_win_y += ((y + 5 - h) - new_win_y - 1) / 10 * 10 + 10; - } - - new_win_z = z; - } - - *df::global::window_x = clip_range(new_win_x, 0, (world->map.x_count - w)); - *df::global::window_y = clip_range(new_win_y, 0, (world->map.y_count - h)); - *df::global::window_z = clip_range(new_win_z, 0, (world->map.z_count - 1)); - - ui_sidebar_menus->minimap.need_render = true; - ui_sidebar_menus->minimap.need_scan = true; - - return; -} - -void Gui::pauseRecenter(int32_t x, int32_t y, int32_t z, bool pause) -{ // Reverse-engineered from DF announcement code - if (*gamemode != game_mode::DWARF) - return; - - resetDwarfmodeView(pause); - - if (x != -30000) - recenterViewscreen(x, y, z, report_zoom_type::Item); - - if (init->input.pause_zoom_no_interface_ms > 0) - { - gview->shutdown_interface_tickcount = Core::getInstance().p->getTickCount(); - gview->shutdown_interface_for_ms = init->input.pause_zoom_no_interface_ms; - } - - return; -} - Gui::DwarfmodeDims getDwarfmodeViewDims_default() { Gui::DwarfmodeDims dims; @@ -2059,38 +2000,68 @@ void Gui::resetDwarfmodeView(bool pause) *df::global::pause_state = true; } -bool Gui::revealInDwarfmodeMap(df::coord pos, bool center) -{ +bool Gui::revealInDwarfmodeMap(int32_t x, int32_t y, int32_t z, bool center) +{ // Reverse-engineered from DF announcement and scrolling code using df::global::window_x; using df::global::window_y; using df::global::window_z; if (!window_x || !window_y || !window_z || !world) return false; - if (!Maps::isValidTilePos(pos)) - return false; auto dims = getDwarfmodeViewDims(); - int w = dims.map_x2 - dims.map_x1 + 1; - int h = dims.map_y2 - dims.map_y1 + 1; - - *window_z = pos.z; + int32_t w = dims.map_x2 - dims.map_x1 + 1; + int32_t h = dims.map_y2 - dims.map_y1 + 1; + int32_t new_win_x, new_win_y, new_win_z; + getViewCoords(new_win_x, new_win_y, new_win_z); - if (center) + if (Maps::isValidTilePos(x, y, z)) { - *window_x = pos.x - w/2; - *window_y = pos.y - h/2; + if (center) + { + new_win_x = x - w / 2; + new_win_y = y - h / 2; + } + else // just bring it on screen + { + if (new_win_x > (x - 5)) // equivalent to: "while (new_win_x > x - 5) new_win_x -= 10;" + new_win_x -= (new_win_x - (x - 5) - 1) / 10 * 10 + 10; + if (new_win_y > (y - 5)) + new_win_y -= (new_win_y - (y - 5) - 1) / 10 * 10 + 10; + if (new_win_x < (x + 5 - w)) + new_win_x += ((x + 5 - w) - new_win_x - 1) / 10 * 10 + 10; + if (new_win_y < (y + 5 - h)) + new_win_y += ((y + 5 - h) - new_win_y - 1) / 10 * 10 + 10; + } + + new_win_z = z; } - else + + *window_x = clip_range(new_win_x, 0, (world->map.x_count - w)); + *window_y = clip_range(new_win_y, 0, (world->map.y_count - h)); + *window_z = clip_range(new_win_z, 0, (world->map.z_count - 1)); + ui_sidebar_menus->minimap.need_render = true; + ui_sidebar_menus->minimap.need_scan = true; + + return true; +} + +bool Gui::pauseRecenter(int32_t x, int32_t y, int32_t z, bool pause) +{ // Reverse-engineered from DF announcement code + if (*gamemode != game_mode::DWARF) + return false; + + resetDwarfmodeView(pause); + + if (Maps::isValidTilePos(x, y, z)) + revealInDwarfmodeMap(x, y, z, false); + + if (init->input.pause_zoom_no_interface_ms > 0) { - while (*window_x + w < pos.x+5) *window_x += 10; - while (*window_y + h < pos.y+5) *window_y += 10; - while (*window_x + 5 > pos.x) *window_x -= 10; - while (*window_y + 5 > pos.y) *window_y -= 10; + gview->shutdown_interface_tickcount = Core::getInstance().p->getTickCount(); + gview->shutdown_interface_for_ms = init->input.pause_zoom_no_interface_ms; } - *window_x = std::max(0, std::min(*window_x, world->map.x_count-w)); - *window_y = std::max(0, std::min(*window_y, world->map.y_count-h)); return true; }