From d88277fa3fe6f4ef7ca7991859ac0478126e9b94 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 31 Jan 2025 07:57:35 -0800 Subject: [PATCH 1/6] Update changelog.txt --- docs/changelog.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index b8d28decc8..1bb7b42bcc 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -37,7 +37,6 @@ Template for new versions: ## API ## Lua -- ``dfhack.units.setAutomaticProfessions``: sets unit labors according to current work detail settings ## Removed @@ -58,6 +57,7 @@ Template for new versions: ## Fixes - `gui/launcher`: ensure commandline is fully visible when searching through history and switching from a very long command to a short command +- `createitem`: output items will now end up at look cursor if active ## Misc Improvements @@ -66,6 +66,7 @@ Template for new versions: ## API ## Lua +- ``dfhack.units.setAutomaticProfessions``: sets unit labors according to current work detail settings ## Removed From e6e1972fb9bd1b97c27c255351f314170d7a8689 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 31 Jan 2025 07:59:53 -0800 Subject: [PATCH 2/6] Support adv look cursor * Update dwarfmode.lua - Make cursor fns support adv mode look * Update Gui.cpp - Make cursor fns support adv mode look * Update changevein.cpp - Use getCursorPos * Update createitem.cpp - Use getCursorPos * Update cursecheck.cpp - Doesn't use cursor * Update stripcaged.cpp - Doesn't use cursor * Update zone.cpp - Use getCursorPos --- library/lua/gui/dwarfmode.lua | 25 +++++++++-- library/modules/Gui.cpp | 80 +++++++++++++++++++++++++++-------- plugins/changevein.cpp | 13 +++--- plugins/createitem.cpp | 10 +++-- plugins/cursecheck.cpp | 7 ++- plugins/devel/stripcaged.cpp | 1 - plugins/zone.cpp | 15 ++++--- 7 files changed, 109 insertions(+), 42 deletions(-) diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index 793acbd520..80d30282cf 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -7,6 +7,7 @@ local utils = require('utils') local dscreen = dfhack.screen +local a_look = df.global.game.main_interface.adventure.look local g_cursor = df.global.cursor local g_sel_rect = df.global.selection_rect local world_map = df.global.world.map @@ -38,17 +39,35 @@ end ---@return df.coord|nil function getCursorPos() - if g_cursor.x >= 0 then + if dfhack.world.isAdventureMode() then + if a_look.open then + return copyall(a_look.cursor) + end + elseif g_cursor.x >= 0 then return copyall(g_cursor) end end function setCursorPos(cursor) - df.global.cursor = copyall(cursor) + if dfhack.world.isAdventureMode() then + a_look.cursor = copyall(cursor) + else + df.global.cursor = copyall(cursor) + end end function clearCursorPos() - df.global.cursor = xyz2pos(nil) + if dfhack.world.isAdventureMode() then + if not a_look.open then + return + end + local u = dfhack.world.getAdventurer() + if u and u.pos:isValid() then + a_look.cursor = copyall(u.pos) + end + else + df.global.cursor = xyz2pos(nil) + end end function getSelection() diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 3e9dd0dda9..ed6ddcba7c 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -2744,9 +2744,18 @@ df::coord Gui::getViewportPos() df::coord Gui::getCursorPos() { using df::global::cursor; + if (World::isAdventureMode()) + { + if (!game) + return df::coord(); + auto &look = game->main_interface.adventure.look; + if (!look.open) + return df::coord(); + return look.cursor; + } + if (!cursor) return df::coord(); - return df::coord(cursor->x, cursor->y, cursor->z); } @@ -2911,7 +2920,7 @@ bool Gui::inRenameBuilding() return false; } -bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) +bool Gui::getViewCoords(int32_t &x, int32_t &y, int32_t &z) { x = *df::global::window_x; y = *df::global::window_y; @@ -2919,7 +2928,7 @@ bool Gui::getViewCoords (int32_t &x, int32_t &y, int32_t &z) return true; } -bool Gui::setViewCoords (const int32_t x, const int32_t y, const int32_t z) +bool Gui::setViewCoords(const int32_t x, const int32_t y, const int32_t z) { (*df::global::window_x) = x; (*df::global::window_y) = y; @@ -2927,32 +2936,67 @@ bool Gui::setViewCoords (const int32_t x, const int32_t y, const int32_t z) return true; } -bool Gui::getCursorCoords (int32_t &x, int32_t &y, int32_t &z) +bool Gui::getCursorCoords(int32_t &x, int32_t &y, int32_t &z) { - x = df::global::cursor->x; - y = df::global::cursor->y; - z = df::global::cursor->z; + using df::global::cursor; + bool is_adv = World::isAdventureMode(); + if (is_adv || !cursor) + { + df::coord p; + if (is_adv && game) + { + auto &look = game->main_interface.adventure.look; + if (look.open) + p = look.cursor; + } + x = p.x; y = p.y; z = p.z; + return p.isValid(); + } + + x = cursor->x; y = cursor->y; z = cursor->z; return has_cursor(); } -bool Gui::getCursorCoords (df::coord &pos) +bool Gui::getCursorCoords(df::coord &pos) { - pos.x = df::global::cursor->x; - pos.y = df::global::cursor->y; - pos.z = df::global::cursor->z; - return has_cursor(); + using df::global::cursor; + df::coord p; + if (World::isAdventureMode()) + { + if (game) + { + auto &look = game->main_interface.adventure.look; + if (look.open) + p = look.cursor; + } + } + else if (cursor) + p = df::coord(cursor->x, cursor->y, cursor->z); + + pos = p; + return p.isValid(); } //FIXME: confine writing of coords to map bounds? -bool Gui::setCursorCoords (const int32_t x, const int32_t y, const int32_t z) +bool Gui::setCursorCoords(const int32_t x, const int32_t y, const int32_t z) { - df::global::cursor->x = x; - df::global::cursor->y = y; - df::global::cursor->z = z; + using df::global::cursor; + if (World::isAdventureMode()) + { + if (!game) + return false; + auto &look = game->main_interface.adventure.look; + look.cursor = df::coord(x, y, z); + return true; + } + if (!cursor) + return false; + + cursor->x = x; cursor->y = y; cursor->z = z; return true; } -bool Gui::getDesignationCoords (int32_t &x, int32_t &y, int32_t &z) +bool Gui::getDesignationCoords(int32_t &x, int32_t &y, int32_t &z) { x = selection_rect->start_x; y = selection_rect->start_y; @@ -2960,7 +3004,7 @@ bool Gui::getDesignationCoords (int32_t &x, int32_t &y, int32_t &z) return (x >= 0) ? false : true; } -bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t z) +bool Gui::setDesignationCoords(const int32_t x, const int32_t y, const int32_t z) { selection_rect->start_x = x; selection_rect->start_y = y; diff --git a/plugins/changevein.cpp b/plugins/changevein.cpp index a73d9584e9..f143a25bc1 100644 --- a/plugins/changevein.cpp +++ b/plugins/changevein.cpp @@ -1,13 +1,14 @@ // Allow changing the material of a mineral inclusion #include "Console.h" +#include "DataDefs.h" #include "Export.h" #include "PluginManager.h" +#include "TileTypes.h" -#include "DataDefs.h" +#include "modules/Gui.h" #include "modules/Maps.h" #include "modules/Materials.h" -#include "TileTypes.h" #include "df/block_square_event.h" #include "df/block_square_event_mineralst.h" @@ -21,7 +22,6 @@ using namespace df::enums; DFHACK_PLUGIN("changevein"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(cursor); constexpr uint8_t NORTH = 0; constexpr uint8_t EAST = 1; @@ -212,7 +212,8 @@ command_result df_changevein (color_ostream &out, vector & parameters) out.printerr("Map is not available!\n"); return CR_FAILURE; } - if (!cursor || cursor->x == -30000) + auto pos = Gui::getCursorPos(); + if (!pos.isValid()) { out.printerr("No cursor detected - please place the cursor over a mineral vein.\n"); return CR_FAILURE; @@ -232,14 +233,14 @@ command_result df_changevein (color_ostream &out, vector & parameters) return CR_FAILURE; } - df::map_block *block = Maps::getTileBlock(cursor->x, cursor->y, cursor->z); + auto block = Maps::getTileBlock(pos); if (!block) { out.printerr("Invalid tile selected.\n"); return CR_FAILURE; } df::block_square_event_mineralst *mineral = NULL; - int tx = cursor->x % 16, ty = cursor->y % 16; + int tx = pos.x % 16, ty = pos.y % 16; for (auto evt : block->block_events) { if (evt->getType() != block_square_event_type::mineral) diff --git a/plugins/createitem.cpp b/plugins/createitem.cpp index 1a720c3f4c..1f4b582047 100644 --- a/plugins/createitem.cpp +++ b/plugins/createitem.cpp @@ -30,7 +30,6 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("createitem"); -REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(gametype); REQUIRE_GLOBAL(cur_year_tick); @@ -84,7 +83,10 @@ bool makeItem(df::unit *unit, df::item_type type, int16_t subtype, int16_t mat_t out_items[i]->moveToGround(building->centerx, building->centery, building->z); } else if (move_to_cursor) - out_items[i]->moveToGround(cursor->x, cursor->y, cursor->z); + { + auto pos = Gui::getCursorPos(); + out_items[i]->moveToGround(pos.x, pos.y, pos.z); + } // else createItem() already put it on the floor at the unit's feet, so we're good // Special logic for creating proper gloves in pairs @@ -395,11 +397,13 @@ command_result df_createitem (color_ostream &out, vector ¶meters) { auto unit = Gui::getSelectedUnit(out, true); if (!unit) { + auto pos = Gui::getCursorPos(); if (*gametype == game_type::ADVENTURE_ARENA || World::isAdventureMode()) { // Use the adventurer unit unit = World::getAdventurer(); + move_to_cursor = pos.isValid(); } - else if (cursor->x >= 0) + else if (pos.isValid()) { // Use the first possible citizen if possible, otherwise the first unit for (auto u : Units::citizensRange(world->units.active)) { unit = u; diff --git a/plugins/cursecheck.cpp b/plugins/cursecheck.cpp index 9c41d73912..958e571271 100644 --- a/plugins/cursecheck.cpp +++ b/plugins/cursecheck.cpp @@ -1,8 +1,8 @@ // cursecheck plugin // -// check single tile or whole map/world for cursed creatures by checking if a valid curse date (!=-1) is set -// if a cursor is active only the selected tile will be observed -// without cursor the whole map will be checked +// check unit or whole map/world for cursed creatures by checking if a valid curse date (!=-1) is set +// if a unit is selected only the selected unit will be observed +// otherwise the whole map will be checked // by default cursed creatures will be only counted // // the tool was intended to help finding vampires but it will also list necromancers, werebeasts and zombies @@ -38,7 +38,6 @@ using namespace df::enums; DFHACK_PLUGIN("cursecheck"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(cursor); enum curses { None = 0, diff --git a/plugins/devel/stripcaged.cpp b/plugins/devel/stripcaged.cpp index 14189bdc30..25f764841f 100644 --- a/plugins/devel/stripcaged.cpp +++ b/plugins/devel/stripcaged.cpp @@ -35,7 +35,6 @@ using std::string; using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::cursor; using df::global::plotinfo; using namespace DFHack::Gui; diff --git a/plugins/zone.cpp b/plugins/zone.cpp index 612e042282..1e69b7e193 100644 --- a/plugins/zone.cpp +++ b/plugins/zone.cpp @@ -55,7 +55,6 @@ using std::vector; DFHACK_PLUGIN_IS_ENABLED(is_enabled); -REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_building_item_cursor); @@ -844,14 +843,15 @@ static void chainInfo(color_ostream & out, df::building* building, bool list_ref static df::building* getAssignableBuildingAtCursor(color_ostream& out) { // set building at cursor position to be new target building - if (cursor->x == -30000) + auto pos = Gui::getCursorPos(); + if (!pos.isValid()) { out.printerr("No cursor; place cursor over activity zone, pen," " pasture, pit, pond, chain, or cage.\n"); return NULL; } - auto building_at_tile = Buildings::findAtTile(Gui::getCursorPos()); + auto building_at_tile = Buildings::findAtTile(pos); // cagezone wants a pen/pit as starting point if (isCage(building_at_tile)) @@ -861,7 +861,7 @@ static df::building* getAssignableBuildingAtCursor(color_ostream& out) } else { - auto zone_at_tile = Buildings::findPenPitAt(Gui::getCursorPos()); + auto zone_at_tile = Buildings::findPenPitAt(pos); if(!zone_at_tile) { out << "No pen/pasture, pit, or cage under cursor!" << endl; @@ -1069,7 +1069,8 @@ static command_result df_zone(color_ostream &out, vector & parameters) } else if(p0 == "zinfo") { - if (cursor->x == -30000) { + auto pos = Gui::getCursorPos(); + if (!pos.isValid()) { out.color(COLOR_RED); out << "No cursor; place cursor over activity zone, chain, or cage." << endl; out.reset_color(); @@ -1081,10 +1082,10 @@ static command_result df_zone(color_ostream &out, vector & parameters) // (doesn't use the findXyzAtCursor() methods because zones might // overlap and contain a cage or chain) vector zones; - Buildings::findCivzonesAt(&zones, Gui::getCursorPos()); + Buildings::findCivzonesAt(&zones, pos); for (auto zone = zones.begin(); zone != zones.end(); ++zone) zoneInfo(out, *zone, verbose); - df::building* building = Buildings::findAtTile(Gui::getCursorPos()); + df::building* building = Buildings::findAtTile(pos); chainInfo(out, building, verbose); cageInfo(out, building, verbose); return CR_OK; From aa61289ab2d06fab8996ae1f868fadcb0fd89b21 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 6 Feb 2025 04:13:51 -0800 Subject: [PATCH 3/6] Update Gui.cpp - Detect adv look focus string --- library/modules/Gui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index ed6ddcba7c..6dfe7f920e 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -848,6 +848,9 @@ static void add_main_interface_focus_strings(const string &baseFocus, vectormain_interface.adventure.jump.open) { focusStrings.push_back(baseFocus + "/Jump"); } + if (game->main_interface.adventure.look.open) { + focusStrings.push_back(baseFocus + "/Look"); + } if (game->main_interface.adventure.movement_options.open) { focusStrings.push_back(baseFocus + "/MovementOptions"); } From 71f92c6085625497940d1788f60687228d3b9e12 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 7 Feb 2025 16:32:29 -0800 Subject: [PATCH 4/6] Update Gui.cpp - Redundant code --- library/modules/Gui.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 6dfe7f920e..1d60c335b6 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -2962,22 +2962,8 @@ bool Gui::getCursorCoords(int32_t &x, int32_t &y, int32_t &z) bool Gui::getCursorCoords(df::coord &pos) { - using df::global::cursor; - df::coord p; - if (World::isAdventureMode()) - { - if (game) - { - auto &look = game->main_interface.adventure.look; - if (look.open) - p = look.cursor; - } - } - else if (cursor) - p = df::coord(cursor->x, cursor->y, cursor->z); - - pos = p; - return p.isValid(); + pos = getCursorPos(); + return pos.isValid(); } //FIXME: confine writing of coords to map bounds? From db49f6d5873e543ad0f72c0050bd34175de3b7a4 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 9 Feb 2025 21:57:50 -0800 Subject: [PATCH 5/6] Update docs/changelog.txt Co-authored-by: Myk --- docs/changelog.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index aee713f373..6d930a3045 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -59,7 +59,6 @@ Template for new versions: - `spectate`: new global keybinding for toggling spectate mode: Ctrl-Shift-S ## Fixes -- `gui/launcher`: ensure commandline is fully visible when searching through history and switching from a very long command to a short command - `createitem`: output items will now end up at look cursor if active - `spectate`: don't allow temporarily modified announcement settings to be written to disk when "auto-unpause" mode is enabled - `changevein`: fix a crash that could occur when attempting to change a vein into itself From b9f7882a3e310ef8b966ec39284bc5f44fbb91ef Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 9 Feb 2025 22:56:01 -0800 Subject: [PATCH 6/6] Update changelog.txt --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 6d930a3045..b36fad7284 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -76,6 +76,7 @@ Template for new versions: ## Lua - ``dfhack.units.setAutomaticProfessions``: sets unit labors according to current work detail settings - ``dfhack.military.removeFromSquad``: Lua API for ``Military::removeFromSquad`` +- ``gui.dwarfmode`` module: ``getCursorPos``, ``setCursorPos``, and ``clearCursorPos`` now operate on the adventure mode look cursor, if active. Clearing the cursor sets it to the active adventurer's position. ## Removed