[tweak/stable-cursor] Keep stable cursor when viewport is near enough

Allow the viewport to move a bit and still keep the cursor location.
develop
Tim Siegel 2022-04-07 10:36:34 -04:00 committed by Myk
parent 0f464b13b3
commit bf60879c81
3 changed files with 25 additions and 4 deletions

@ -442,7 +442,8 @@ Subcommands that persist until disabled or DF quits:
:nestbox-color: Fixes the color of built nestboxes
:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`)
:shift-8-scroll: Gives Shift-8 (or :kbd:`*`) priority when scrolling menus, instead of scrolling the map
:stable-cursor: Saves the exact cursor position between t/q/k/d/b/etc menus of fortress mode.
:stable-cursor: Saves the exact cursor position between t/q/k/d/b/etc menus of fortress mode, if the
map view is near enough to its previous position.
:stone-status-all: Adds an option to toggle the economic status of all stones
:title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu
:tradereq-pet-gender: Displays pet genders on the trade request screen

@ -56,6 +56,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `autochop`: only designate the amount of trees required to reach ``max_logs``
- `autochop`: preferably designate larger trees over smaller ones
- `blueprint`: ``track`` phase renamed to ``carve``. carved fortifications and (optionally) engravings are now captured in blueprints
- `tweak` stable-cursor: Keep the cursor stable even when the viewport moves a small amount
## Documentation
- Add more examples to the plugin skeleton files so they are more informative for a newbie

@ -32,6 +32,26 @@ struct stable_cursor_hook : df::viewscreen_dwarfmodest
}
}
bool check_viewport_near_enough()
{
df::coord view = Gui::getViewportPos();
auto dims = Gui::getDwarfmodeViewDims();
int view_size = min(dims.map_x2 - dims.map_x1, dims.map_y2 - dims.map_y1);
// Heuristic to keep the cursor position if the view is still in the
// part of the map that was already visible
int near_enough_distance = min(30, view_size / 2);
return
// Is the viewport near enough to the old viewport?
abs(view.x - last_view.x) <= near_enough_distance &&
abs(view.y - last_view.y) <= near_enough_distance &&
view.z == last_view.z &&
// And is the last cursor visible in the current viewport?
last_cursor.x >= view.x && last_cursor.y >= view.y &&
last_cursor.x <= view.x + dims.map_x2 - dims.map_x1 &&
last_cursor.y <= view.y + dims.map_y2 - dims.map_y1;
}
DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input))
{
bool was_default = check_default();
@ -47,9 +67,8 @@ struct stable_cursor_hook : df::viewscreen_dwarfmodest
{
last_view = view; last_cursor = cursor;
}
else if (!is_default && was_default &&
Gui::getViewportPos() == last_view &&
last_cursor.isValid() && cur_cursor.isValid())
else if (!is_default && was_default && cur_cursor.isValid() &&
last_cursor.isValid() && check_viewport_near_enough())
{
Gui::setCursorCoords(last_cursor.x, last_cursor.y, last_cursor.z);
Gui::refreshSidebar();