From d8e6665529e41b143fb65aa7ba1fdaa6645275c2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 12 Feb 2025 05:53:48 -0800 Subject: [PATCH 1/6] Use guidm cursor fns * colonies.lua - guidm cursor * devel/light.lua (unavailable) - guidm cursor * devel/query.lua - guidm cursor; same_xyz * devel/tree-info.lua - guidm cursor * gui/advfort.lua (unavailable) - guidm cursor; same_xyz * gui/blueprint.lua - guidm cursor * gui/companion-order.lua (unavailable) - guidm cursor; same_xyz * gui/create-item.lua - add pos arg * gui/tiletypes.lua - guidm cursor * modtools/create-item.lua - respect opts.pos, handle inside hackWish * hfs-pit.lua - guidm cursor; fix up tiletypes * launch.lua - guidm cursor; fix projectile flag * putontable.lua - guidm cursor; same_xyz * source.lua - guidm cursor * stripcaged.lua - guidm cursor * teleport.lua - guidm cursor * toggle-kbd-cursor.lua - use clearCursorPos; exclude adv mode * docs/extinguish.rst - adv tag * docs/firestarter.rst - adv tag * docs/launch.rst - reinstated * docs/putontable.rst - reinstated * docs/toggle-kbd-cursor.rst - fort tag * docs/gui/create-item.rst - add pos arg * docs/modtools/create-item.rst - suggest "here" for pos * Update changelog.txt --- changelog.txt | 9 ++++++- colonies.lua | 6 +++-- devel/light.lua | 8 +----- devel/query.lua | 16 +++++------- devel/tree-info.lua | 7 ++++- docs/extinguish.rst | 2 +- docs/firestarter.rst | 2 +- docs/gui/create-item.rst | 4 +++ docs/launch.rst | 2 +- docs/modtools/create-item.rst | 3 ++- docs/putontable.rst | 2 +- docs/toggle-kbd-cursor.rst | 9 +++++-- gui/advfort.lua | 48 ++++++++++++++++++----------------- gui/blueprint.lua | 2 +- gui/companion-order.lua | 17 +++++-------- gui/create-item.lua | 9 ++++++- gui/tiletypes.lua | 10 ++++---- hfs-pit.lua | 40 ++++++++++++++--------------- launch.lua | 16 ++++++------ modtools/create-item.lua | 34 ++++++++++++++++--------- putontable.lua | 8 +++--- source.lua | 7 ++--- stripcaged.lua | 5 ++-- teleport.lua | 8 +++--- toggle-kbd-cursor.lua | 7 +++-- 25 files changed, 160 insertions(+), 121 deletions(-) diff --git a/changelog.txt b/changelog.txt index 4965da0d76..38d56e424d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -30,12 +30,18 @@ Template for new versions: - `devel/export-map`: export map tile data to a JSON file - `autocheese`: automatically make cheese using barrels that have accumulated sufficient milk - `gui/spectate`: interactive UI for configuring `spectate` +- `launch`: (reinstated) thrash your enemies with a flying suplex +- `putontable`: (reinstated) make an item appear on a table like in adventure mode ## New Features -- `advtools`: new ``advtools.fastcombat`` overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys +- `advtools`: new ``advtools.fastcombat`` overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys ## Fixes - `position`: support for adv mode look cursor +- `devel/query`, `devel/tree-info`, `hfs-pit`, `colonies`: now function in adventure mode +- `hfs-pit`: fix up tiletypes of pit walls, better placement of stairs (w/r/t eerie pits and ramp tops) +- `modtools/create-item`: ``hackWish`` now respects ``opts.pos`` and will spawn items there if provided +- `toggle-kbd-cursor`: exclude adventure mode because it isn't compatible ## Misc Improvements - `hide-tutorials`: handle tutorial popups for adventure mode @@ -43,6 +49,7 @@ Template for new versions: - `gui/notify`: moody dwarf notification turns red when they can't reach workshop or items - `gui/confirm`: in the delete manager order confirmation dialog, show a description of which order you have selected to delete - `position`: display both adventurer and site pos simultaneously. Display map block pos+offset of selected tile. +- `gui/create-item`: now accepts a ``pos`` argument of where to spawn items ## Removed diff --git a/colonies.lua b/colonies.lua index 554795229e..48b8094d83 100644 --- a/colonies.lua +++ b/colonies.lua @@ -20,6 +20,8 @@ and ``colonies convert TERMITE`` ends your beekeeping industry. ]====] +local guidm = require('gui.dwarfmode') + function findVermin(target_verm) for k,v in ipairs(df.global.world.raws.creatures.all) do if v.creature_id == target_verm then @@ -50,8 +52,8 @@ function convert_vermin_to(target_verm) end function place_vermin(target_verm) - local pos = copyall(df.global.cursor) - if pos.x == -30000 then + local pos = guidm.getCursorPos() + if not pos then qerror("Cursor must be pointing somewhere") end local verm = df.vermin:new() diff --git a/devel/light.lua b/devel/light.lua index aa741f4d07..3786a26976 100644 --- a/devel/light.lua +++ b/devel/light.lua @@ -27,12 +27,6 @@ function setCell(x,y,cell) cell.bo=cell.bo or {r=0,g=0,b=0} render.setCell(x,y,cell) end -function getCursorPos() - local g_cursor=df.global.cursor - if g_cursor.x ~= -30000 then - return copyall(g_cursor) - end -end --luacheck: skip function falloff(color,sqDist,maxdist) local v1=1/(sqDist/maxdist+1) @@ -273,7 +267,7 @@ function LightOverlay:calculateLightSun() end end function LightOverlay:calculateLightCursor() - local c=getCursorPos() + local c=guidm.getCursorPos() if c then diff --git a/devel/query.lua b/devel/query.lua index 18859eaaed..610003873c 100644 --- a/devel/query.lua +++ b/devel/query.lua @@ -2,7 +2,8 @@ -- Written by Josh Cooper(cppcooper) on 2017-12-21, last modified: 2021-06-13 -- Version: 3.2 --luacheck:skip-entirely -local utils=require('utils') +local guidm = require('gui.dwarfmode') +local utils = require('utils') local validArgs = utils.invert({ 'help', @@ -221,14 +222,11 @@ function getSelectionData() elseif args.job then debugf(0,"job selection") selection = dfhack.gui.getSelectedJob(true) - if selection == nil and df.global.cursor.x >= 0 then - local pos = { x=df.global.cursor.x, - y=df.global.cursor.y, - z=df.global.cursor.z } + local pos = guidm.getCursorPos() + if selection == nil and pos then print("searching for a job at the cursor") for _link, job in utils.listpairs(df.global.world.jobs.list) do - local jp = job.pos - if jp.x == pos.x and jp.y == pos.y and jp.z == pos.z then + if same_xyz(job.pos, pos) then if selection == nil then selection = {} end @@ -240,7 +238,7 @@ function getSelectionData() path_info_pattern = path_info elseif args.tile then debugf(0,"tile selection") - local pos = copyall(df.global.cursor) + local pos = guidm.getCursorPos() selection = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z) bpos = selection.map_pos path_info = string.format("tile[%d][%d][%d]",pos.x,pos.y,pos.z) @@ -249,7 +247,7 @@ function getSelectionData() tiley = pos.y%16 elseif args.block then debugf(0,"block selection") - local pos = copyall(df.global.cursor) + local pos = guidm.getCursorPos() selection = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z) bpos = selection.map_pos path_info = string.format("blocks[%d][%d][%d]",bpos.x,bpos.y,bpos.z) diff --git a/devel/tree-info.lua b/devel/tree-info.lua index 7bf4b42e41..d4d23b0c55 100644 --- a/devel/tree-info.lua +++ b/devel/tree-info.lua @@ -1,5 +1,6 @@ --Print a tree_info visualization of the tree at the cursor. --@module = true +local guidm = require('gui.dwarfmode') -- [w][n][e][s] local branch_chars = { @@ -172,7 +173,11 @@ function printTree(t) end if not dfhack_flags.module then - local p = dfhack.maps.getPlantAtTile(copyall(df.global.cursor)) + local p = guidm.getCursorPos() + if not p then + qerror('No cursor!') + end + p = dfhack.maps.getPlantAtTile(p) if p and p.tree_info then printTree(p.tree_info) else diff --git a/docs/extinguish.rst b/docs/extinguish.rst index ceaae431d2..67ba8c7797 100644 --- a/docs/extinguish.rst +++ b/docs/extinguish.rst @@ -3,7 +3,7 @@ extinguish .. dfhack-tool:: :summary: Put out fires. - :tags: fort armok buildings items map units + :tags: fort adventure armok buildings items map units With this tool, you can put out fires affecting map tiles, plants, units, items, and buildings. diff --git a/docs/firestarter.rst b/docs/firestarter.rst index 5e610d2e92..08e16e0626 100644 --- a/docs/firestarter.rst +++ b/docs/firestarter.rst @@ -3,7 +3,7 @@ firestarter .. dfhack-tool:: :summary: Lights things on fire. - :tags: fort armok items map units + :tags: fort adventure armok items map units Feel the need to burn something? Set items, locations, or even entire inventories on fire! Use while viewing an item, with the cursor over a map tile, diff --git a/docs/gui/create-item.rst b/docs/gui/create-item.rst index ef501afa65..580dec5f1d 100644 --- a/docs/gui/create-item.rst +++ b/docs/gui/create-item.rst @@ -42,6 +42,10 @@ Options ``-f``, ``--unrestricted`` Don't restrict the material options to only those that are normally appropriate for the selected item type. +``-p``, ``--pos ,,`` + If specified, items will be spawned at the given coordinates instead of at + the creator unit's feet. ``here`` can be used in place of ``,,`` + to use the active keyboard cursor. ``--startup`` Instead of showing the item creation interface, start monitoring for a modded reaction with a code of ``DFHACK_WISH``. When a reaction with that diff --git a/docs/launch.rst b/docs/launch.rst index 6b884fcfb7..9f3648b88f 100644 --- a/docs/launch.rst +++ b/docs/launch.rst @@ -3,7 +3,7 @@ launch .. dfhack-tool:: :summary: Thrash your enemies with a flying suplex. - :tags: unavailable + :tags: adventure armok units Attack another unit and then run this command to grab them and fly in a glorious parabolic arc to where you have placed the cursor. You'll land safely and your diff --git a/docs/modtools/create-item.rst b/docs/modtools/create-item.rst index fe96abdd47..a7fbd6ef65 100644 --- a/docs/modtools/create-item.rst +++ b/docs/modtools/create-item.rst @@ -48,4 +48,5 @@ Options caste associated with it. ``-p``, ``--pos ,,`` If specified, items will be spawned at the given coordinates instead of at - the creator unit's feet. + the creator unit's feet. ``here`` can be used in place of ``,,`` + to use the active keyboard cursor. diff --git a/docs/putontable.rst b/docs/putontable.rst index e880ac896d..10d94705a6 100644 --- a/docs/putontable.rst +++ b/docs/putontable.rst @@ -3,7 +3,7 @@ putontable .. dfhack-tool:: :summary: Make an item appear on a table. - :tags: unavailable + :tags: adventure fort armok buildings items To use this tool, move an item to the ground on the same tile as a built table. Then, place the cursor over the table and item and run this command. The item diff --git a/docs/toggle-kbd-cursor.rst b/docs/toggle-kbd-cursor.rst index 80b0e08e62..aba577aceb 100644 --- a/docs/toggle-kbd-cursor.rst +++ b/docs/toggle-kbd-cursor.rst @@ -3,9 +3,14 @@ toggle-kbd-cursor .. dfhack-tool:: :summary: Toggles the keyboard cursor. - :tags: interface + :tags: fort interface -This tool simply toggles the keyboard cursor so you can quickly switch it on when you need it. Many other tools, like `autodump`, need a keyboard cursor for selecting a target tile. Note that you'll still need to enter an interface mode where the keyboard cursor is visible, like mining mode or dumping mode, in order to use the cursor. +This tool simply toggles the keyboard cursor so you can quickly switch it on +when you need it. Many other tools, like `autodump`, need a keyboard cursor for +selecting a target tile. Note that you'll still need to enter an interface mode +where the keyboard cursor is visible, like mining mode or dumping mode, in +order to use the cursor. This tool does not function in adventure mode because +the adventurer cursor cannot be trivially toggled. Usage ----- diff --git a/gui/advfort.lua b/gui/advfort.lua index f63ad98173..1ce1e3f5c6 100644 --- a/gui/advfort.lua +++ b/gui/advfort.lua @@ -69,14 +69,15 @@ build_filter.HUMANish={ --[[ FIXME: maybe let player select which to disable?]] for k,v in ipairs(df.global.plotinfo.economic_stone) do df.global.plotinfo.economic_stone[k]=0 end -local gui = require 'gui' -local wid=require 'gui.widgets' -local dialog=require 'gui.dialogs' -local buildings=require 'dfhack.buildings' -local bdialog=require 'gui.buildings' -local workshopJobs=require 'dfhack.workshops' -local utils=require 'utils' -local gscript=require 'gui.script' +local gui = require('gui') +local guidm = require('gui.dwarfmode') +local wid = require('gui.widgets') +local dialog = require('gui.dialogs') +local buildings = require('dfhack.buildings') +local bdialog = require('gui.buildings') +local workshopJobs = require('dfhack.workshops') +local utils = require('utils') +local gscript = require('gui.script') local advfort_items = reqscript('internal/advfort/advfort_items') @@ -375,7 +376,7 @@ end function AssignUnitToJob(job,unit,unit_pos) job.general_refs:insert("#",{new=df.general_ref_unit_workerst,unit_id=unit.id}) unit.job.current_job=job - unit_pos=unit_pos or {x=job.pos.x,y=job.pos.y,z=job.pos.z} + unit_pos=unit_pos or copyall(job.pos) unit.path.dest:assign(unit_pos) return true end @@ -383,7 +384,7 @@ function SetCreatureRef(args) local job=args.job local pos=args.pos for k,v in pairs(df.global.world.units.active) do - if v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z then + if same_xyz(v.pos, pos) then job.general_refs:insert("#",{new=df.general_ref_unit_cageest,unit_id=v.id}) return end @@ -393,7 +394,7 @@ end function SetWebRef(args) local pos=args.pos for k,v in pairs(df.global.world.items.other.ANY_WEBS) do - if v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z then + if same_xyz(v.pos, pos) then args.job.general_refs:insert("#",{new=df.general_ref_item,item_id=v.id}) return end @@ -403,7 +404,7 @@ function SetPatientRef(args) local job=args.job local pos=args.pos for k,v in pairs(df.global.world.units.active) do - if v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z then + if same_xyz(v.pos, pos) then job.general_refs:insert("#",{new=df.general_ref_unit_patientst,unit_id=v.id}) return end @@ -481,7 +482,7 @@ end function SameSquare(args) local pos1=args.pos local pos2=args.from_pos - if pos1.x==pos2.x and pos1.y==pos2.y and pos1.z==pos2.z then + if same_xyz(pos1, pos2) then return true else return false, "Can only do it on same square" @@ -547,7 +548,7 @@ end function IsUnit(args) local pos=args.pos for k,v in pairs(df.global.world.units.active) do - if v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z then + if same_xyz(v.pos, pos) then return true end end @@ -556,7 +557,7 @@ end function itemsAtPos(pos,tbl) local ret=tbl or {} for k,v in pairs(df.global.world.items.other.IN_PLAY) do - if v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z and v.flags.on_ground then + if v.flags.on_ground and same_xyz(v.pos, pos) then table.insert(ret,v) end end @@ -776,7 +777,7 @@ function EnumItems(args) end elseif args.pos~=nil then for k,v in pairs(df.global.world.items.other.IN_PLAY) do - if v.pos.x==args.pos.x and v.pos.y==args.pos.y and v.pos.z==args.pos.z and v.flags.on_ground then + if v.flags.on_ground and same_xyz(v.pos, args.pos) then AddItem(ret,v,args.deep) end end @@ -1303,7 +1304,7 @@ function siegeWeaponActionChosen(args,actionid) end args.job_type=action args.unit=dfhack.world.getAdventurer() - local from_pos={x=args.unit.pos.x,y=args.unit.pos.y, z=args.unit.pos.z} + local from_pos=copyall(args.unit.pos) args.from_pos=from_pos args.pos=from_pos elseif actionid==3 then --Fire @@ -1313,7 +1314,7 @@ function siegeWeaponActionChosen(args,actionid) end args.job_type=action args.unit=dfhack.world.getAdventurer() - local from_pos={x=args.unit.pos.x,y=args.unit.pos.y, z=args.unit.pos.z} + local from_pos=copyall(args.unit.pos) args.from_pos=from_pos args.pos=from_pos end @@ -1397,7 +1398,7 @@ function usetool:openShopWindow(building) local filter_pile=workshopJobs.getJobs(building:getType(),building:getSubtype(),building:getCustomType()) if filter_pile then - local state={unit=adv,from_pos={x=adv.pos.x,y=adv.pos.y, z=adv.pos.z},building=building,screen=self,bld=building} + local state={unit=adv,from_pos=copyall(adv.pos),building=building,screen=self,bld=building} local choices={} for k,v in pairs(filter_pile) do table.insert(choices,{job_id=0,text=v.name:lower(),filter=v}) @@ -1687,15 +1688,16 @@ function usetool:fieldInput(keys) unit=adv, pos=moddedpos(adv.pos,MOVEMENT_KEYS[code]), dir=MOVEMENT_KEYS[code], - from_pos={x=adv.pos.x,y=adv.pos.y, z=adv.pos.z}, + from_pos=copyall(adv.pos), post_actions=cur_mode[4], pre_actions=cur_mode[5], job_type=cur_mode[2], screen=self} if code=="SELECT" then --do job in the distance, TODO: check if you can still cheat-mine (and co.) remotely - if df.global.cursor.x~=-30000 then - state.pos={x=df.global.cursor.x,y=df.global.cursor.y,z=df.global.cursor.z} + local cursor=guidm.getCursorPos() + if cursor then + state.pos=cursor else break end @@ -1747,7 +1749,7 @@ function usetool:onInput(keys) local adv=dfhack.world.getAdventurer() if keys.LEAVESCREEN then - if df.global.cursor.x~=-30000 then --if not poiting at anything + if guidm.getCursorPos() then --if not poiting at anything self:sendInputToParent("LEAVESCREEN") --leave poiting else self:dismiss() --leave the adv-tools all together diff --git a/gui/blueprint.lua b/gui/blueprint.lua index abedc26654..2df37f0106 100644 --- a/gui/blueprint.lua +++ b/gui/blueprint.lua @@ -381,7 +381,7 @@ function Blueprint:onShow() end function Blueprint:save_cursor_pos() - self.saved_cursor = copyall(df.global.cursor) + self.saved_cursor = guidm.getCursorPos() end function Blueprint:is_setting_start_pos() diff --git a/gui/companion-order.lua b/gui/companion-order.lua index 71bc644c22..814b4d9d8a 100644 --- a/gui/companion-order.lua +++ b/gui/companion-order.lua @@ -25,10 +25,11 @@ Can be called with '-c' flag to display "cheating" commands. ]====] local gui = require 'gui' +local guidm = require 'gui.dwarfmode' local dlg = require 'gui.dialogs' local args={...} local is_cheat=(#args>0 and args[1]=="-c") -local cursor=xyz2pos(df.global.cursor.x,df.global.cursor.y,df.global.cursor.z) +local cursor=guidm.getCursorPos() local permited_equips={} permited_equips[df.item_backpackst]="UPPERBODY" @@ -46,7 +47,7 @@ function DoesHaveSubtype(item) return true end function CheckCursor(p) - if p.x==-30000 then + if not p then dlg.showMessage( 'Companion orders', 'You must have a cursor on some tile!', COLOR_LIGHTRED @@ -55,12 +56,6 @@ function CheckCursor(p) end return true end -function getxyz() -- this will return pointers x,y and z coordinates. - local x=df.global.cursor.x - local y=df.global.cursor.y - local z=df.global.cursor.z - return x,y,z -- return the coords -end function EnumBodyEquipable(race_id,caste_id) local caste=dfhack.units.getCasteRaw(race_id,caste_id) @@ -190,7 +185,7 @@ end function GetItemsAtPos(pos) local ret={} for k,v in pairs(df.global.world.items.other.IN_PLAY) do - if v.flags.on_ground and v.pos.x==pos.x and v.pos.y==pos.y and v.pos.z==pos.z then + if v.flags.on_ground and same_xyz(v.pos, pos) then table.insert(ret,v) end end @@ -232,7 +227,7 @@ function move_unit( unit,tx,ty,tz ) --copied from http/commands.lua with minor m unit.idle_area_threshold=0 unit.follow_distance=50 --invalidate old path - unit.path.dest={x=unit.idle_area.x,y=unit.idle_area.y,z=unit.idle_area.z} + unit.path.dest=copyall(unit.idle_area) unit.path.goal=df.unit_path_goal.SeekStation unit.path.path.x:resize(0) unit.path.path.y:resize(0) @@ -394,7 +389,7 @@ end}, return false end adv=dfhack.world.getAdventurer() - item=GetItemsAtPos(df.global.cursor)[1] + item=GetItemsAtPos(cursor)[1] print(item.id) for k,v in pairs(unit_list) do v.riding_item_id=item.id diff --git a/gui/create-item.lua b/gui/create-item.lua index ee224fca57..cf5c12a25d 100644 --- a/gui/create-item.lua +++ b/gui/create-item.lua @@ -232,7 +232,8 @@ local default_accessors = { partlayerok, partlayerID = script.showListPrompt('Wish', 'What creature material should it be?', COLOR_LIGHTGREEN, getCreatureMaterialList(raceId, casteId), 1, true) else - --the offsets here are because indexes in lua are wonky (some start at 0, some start at 1), so we adjust for that, as well as the index offset created by inserting the "generic" option at the start of the body part selection prompt + --the offsets here are because indexes in lua are wonky (some start at 0, some start at 1), so we adjust for that, + --as well as the index offset created by inserting the "generic" option at the start of the body part selection prompt bodypart = bodypart - 2 partlayerok, partlayerID = script.showListPrompt('Wish', 'What tissue layer should it be?', COLOR_LIGHTGREEN, getCreaturePartLayerList(raceId, casteId, bodypart), 1, true) @@ -275,6 +276,12 @@ local positionals = argparse.processArgsGetopt({ ... }, { hasArg = true, handler = function(arg) opts.count = argparse.nonnegativeInt(arg, 'count') end, }, + { + 'p', + 'pos', + hasArg = true, + handler = function(arg) opts.pos = argparse.coords(arg, 'pos') end, + }, }) if positionals[1] == 'help' then opts.help = true end diff --git a/gui/tiletypes.lua b/gui/tiletypes.lua index 193f1ca0bb..513fd9181c 100644 --- a/gui/tiletypes.lua +++ b/gui/tiletypes.lua @@ -767,11 +767,11 @@ function BoxSelection:onInput(keys) end local mousePos = dfhack.gui.getMousePos(true) - local cursorPos = copyall(df.global.cursor) - cursorPos.x = math.max(math.min(cursorPos.x, df.global.world.map.x_count - 1), 0) - cursorPos.y = math.max(math.min(cursorPos.y, df.global.world.map.y_count - 1), 0) - + local cursorPos = guidm.getCursorPos() + if cursorPos and keys.SELECT then + cursorPos.x = math.max(math.min(cursorPos.x, df.global.world.map.x_count - 1), 0) + cursorPos.y = math.max(math.min(cursorPos.y, df.global.world.map.y_count - 1), 0) if self.first_point and not self.last_point then if not self.flat or cursorPos.z == self.first_point.z then self.last_point = cursorPos @@ -834,7 +834,7 @@ function BoxSelection:onRenderFrame(dc, rect) if not box then local selectedPos = dfhack.gui.getMousePos(true) if self.useCursor or not selectedPos then - selectedPos = copyall(df.global.cursor) + selectedPos = guidm.getCursorPos() or xyz2pos(nil) selectedPos.x = math.max(math.min(selectedPos.x, df.global.world.map.x_count - 1), 0) selectedPos.y = math.max(math.min(selectedPos.y, df.global.world.map.y_count - 1), 0) end diff --git a/hfs-pit.lua b/hfs-pit.lua index fb4cf7341b..a89c3e6eb3 100644 --- a/hfs-pit.lua +++ b/hfs-pit.lua @@ -27,6 +27,7 @@ Examples:: ]====] +local guidm = require('gui.dwarfmode') local args={...} if args[1] == '?' or args[1] == 'help' then @@ -34,7 +35,7 @@ if args[1] == '?' or args[1] == 'help' then return end -local pos = copyall(df.global.cursor) +local pos = guidm.getCursorPos() local size = tonumber(args[1]) if size == nil or size < 1 then size = 1 end @@ -49,7 +50,7 @@ for index, feature in ipairs(df.global.world.features.map_features) do end end -if pos.x==-30000 then +if not pos then qerror("Select a location by placing the cursor") end local x = 0 @@ -62,41 +63,40 @@ for x=pos.x-size,pos.x+size,1 do while z <= pos.z do local block = dfhack.maps.ensureTileBlock(x,y,z) if block then - if block.tiletype[x%16][y%16] ~= 335 then + local old_tt = block.tiletype[x%16][y%16] + if not hitAir and old_tt ~= df.tiletype.FeatureWall and old_tt ~= df.tiletype.EeriePit then hitAir = true end - if hitAir == true then + if hitAir then if not hitCeiling then if block.global_feature ~= underworldLayer or z > 10 then hitCeiling = true end if stairs == 1 and x == pos.x and y == pos.y then - if block.tiletype[x%16][y%16] == 32 then + if old_tt == df.tiletype.OpenSpace or old_tt == df.tiletype.RampTop then if z == pos.z then - block.tiletype[x%16][y%16] = 56 + block.tiletype[x%16][y%16] = df.tiletype.StoneStairD else - block.tiletype[x%16][y%16] = 55 + block.tiletype[x%16][y%16] = df.tiletype.StoneStairUD end else - block.tiletype[x%16][y%16] = 57 + block.tiletype[x%16][y%16] = df.tiletype.StoneStairU end end end - if hitCeiling == true then + if hitCeiling then local needsWall = block.designation[x%16][y%16].flow_size > 0 or wallOff == 1 if (x == pos.x-size or x == pos.x+size or y == pos.y-size or y == pos.y+size) and z==pos.z then --Do nothing, this is the lip of the hole - elseif x == pos.x-size and y == pos.y-size then if needsWall == true then block.tiletype[x%16][y%16]=320 end - elseif x == pos.x-size and y == pos.y+size then if needsWall == true then block.tiletype[x%16][y%16]=321 end - elseif x == pos.x+size and y == pos.y+size then if needsWall == true then block.tiletype[x%16][y%16]=322 end - elseif x == pos.x+size and y == pos.y-size then if needsWall == true then block.tiletype[x%16][y%16]=323 end - elseif x == pos.x-size or x == pos.x+size then if needsWall == true then block.tiletype[x%16][y%16]=324 end - elseif y == pos.y-size or y == pos.y+size then if needsWall == true then block.tiletype[x%16][y%16]=325 end + elseif x == pos.x-size and y == pos.y-size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothRD end + elseif x == pos.x-size and y == pos.y+size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothRU end + elseif x == pos.x+size and y == pos.y+size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothLU end + elseif x == pos.x+size and y == pos.y-size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothLD end + elseif x == pos.x-size or x == pos.x+size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothUD end + elseif y == pos.y-size or y == pos.y+size then if needsWall then block.tiletype[x%16][y%16]=df.tiletype.StoneWallSmoothLR end elseif stairs == 1 and x == pos.x and y == pos.y then - if z == pos.z then block.tiletype[x%16][y%16]=56 - else block.tiletype[x%16][y%16]=55 end - else block.tiletype[x%16][y%16]=32 + if z == pos.z then block.tiletype[x%16][y%16]=df.tiletype.StoneStairD + else block.tiletype[x%16][y%16]=df.tiletype.StoneStairUD end + else block.tiletype[x%16][y%16]=df.tiletype.OpenSpace end - block.designation[x%16][y%16].hidden = false - --block.designation[x%16][y%16].liquid_type = true -- if true, magma. if false, water. block.designation[x%16][y%16].flow_size = 0 dfhack.maps.enableBlockUpdates(block) block.designation[x%16][y%16].flow_forbid = false diff --git a/launch.lua b/launch.lua index 57cf1ef40d..40aaf26995 100644 --- a/launch.lua +++ b/launch.lua @@ -8,16 +8,16 @@ Activate with a cursor on screen and you will go there rapidly. Attack something first to ride them there. ]====] +local guidm = require('gui.dwarfmode') + function launch(unitSource,unitRider) - local curpos - if df.global.adventure.menu == df.ui_advmode_menu.Look then - curpos = df.global.cursor - elseif df.global.gamemode == df.game_mode.ADVENTURE then - qerror("No [l] cursor located! You would have slammed into the ground and exploded.") - else + if not dfhack.world.isAdventureMode() then qerror("Must be used in adventurer mode or the arena!") end - + local curpos = guidm.getCursorPos() + if not curpos then + qerror("No cursor located! You would have slammed into the ground and exploded.") + end local count=0 local l = df.global.world.projectiles.all @@ -61,7 +61,7 @@ function launch(unitSource,unitRider) proj.flags.high_flying=true --this probably doesn't do anything, let me know if you figure out what it is proj.flags.parabolic=true proj.flags.no_collide=true - proj.flags.unk9=true + proj.flags.no_adv_pause=true proj.speed_x=resultx*10000 proj.speed_y=resulty*10000 proj.speed_z=resultz*15000 --higher z speed makes it easier to reach a target safely diff --git a/modtools/create-item.lua b/modtools/create-item.lua index 95811af968..03a60b352f 100644 --- a/modtools/create-item.lua +++ b/modtools/create-item.lua @@ -78,7 +78,10 @@ local function createCorpsePiece(creator, bodypart, partlayer, creatureID, caste casteID = tonumber(casteID) bodypart = tonumber(bodypart) partlayer = tonumber(partlayer) - -- somewhat similar to the bodypart variable below, a value of -1 here means that the user wants to spawn a whole body part. we set the partlayer to 0 (outermost) because the specific layer isn't important, and we're spawning them all anyway. if it's a generic corpsepiece we ignore it, as it gets added to anyway below (we can't do it below because between here and there there's lines that reference the part layer + -- somewhat similar to the bodypart variable below, a value of -1 here means that the user wants to spawn a whole body part. + -- we set the partlayer to 0 (outermost) because the specific layer isn't important, and we're spawning them all anyway. + -- if it's a generic corpsepiece we ignore it, as it gets added to anyway below (we can't do it below because between here and + -- there there's lines that reference the part layer if partlayer == -1 and not generic then partlayer = 0 wholePart = true @@ -177,7 +180,8 @@ local function createCorpsePiece(creator, bodypart, partlayer, creatureID, caste item.race = creatureID item.normal_race = creatureID item.normal_caste = casteID - -- usually the first two castes are for the creature's sex, so we set the item's sex to the caste if both the creature has one and it's a valid sex id (0 or 1) + -- usually the first two castes are for the creature's sex, so we set the item's sex to + -- the caste if both the creature has one and it's a valid sex id (0 or 1) if casteID < 2 and #(creatorRaceRaw.caste) > 1 then item.sex = casteID else @@ -198,12 +202,14 @@ local function createCorpsePiece(creator, bodypart, partlayer, creatureID, caste for i,n in pairs(creatorBody.body_parts) do -- inserts item.body.body_part_relsize:insert('#', n.relsize) - item.body.components.body_part_status:insert(i, creator.body.components.body_part_status[0]) --copy the status of the creator's first part to every body_part_status of the desired creature + --copy the status of the creator's first part to every body_part_status of the desired creature + item.body.components.body_part_status:insert(i, creator.body.components.body_part_status[0]) item.body.components.body_part_status[i].missing = true end for i in pairs(creatorBody.layer_part) do -- inserts - item.body.components.layer_status:insert(i, creator.body.components.layer_status[0]) --copy the layer status of the creator's first layer to every layer_status of the desired creature + -- copy the layer status of the creator's first layer to every layer_status of the desired creature + item.body.components.layer_status:insert(i, creator.body.components.layer_status[0]) item.body.components.layer_status[i].gone = true end if item_type == 'CORPSE' then @@ -222,7 +228,9 @@ local function createCorpsePiece(creator, bodypart, partlayer, creatureID, caste item.body.components.layer_status[creatorBody.body_parts[i].layers[n].layer_id].gone = false else -- search through the target creature's body parts and bring back every one which has the desired material - if creatorRaceRaw.tissue[creatorBody.body_parts[i].layers[n].tissue_id].tissue_material_str[1] == layerMat and creatorBody.body_parts[i].token ~= 'SKULL' and not creatorBody.body_parts[i].flags.SMALL then + if creatorRaceRaw.tissue[creatorBody.body_parts[i].layers[n].tissue_id].tissue_material_str[1] == layerMat and + creatorBody.body_parts[i].token ~= 'SKULL' and not creatorBody.body_parts[i].flags.SMALL then + item.body.components.body_part_status[i].missing = false item.body.components.layer_status[creatorBody.body_parts[i].layers[n].layer_id].gone = false -- save the index of the bone layer to a variable @@ -251,7 +259,8 @@ end local function createItem(mat, itemType, quality, creator, description, amount) -- The "reaction-gloves" tweak can cause this to create multiple gloves local items = dfhack.items.createItem(creator, itemType[1], itemType[2], mat[1], mat[2]) - assert(#items > 0, ('failed to create item: item_type: %s, item_subtype: %s, mat_type: %s, mat_index: %s, unit: %s'):format(itemType[1], itemType[2], mat[1], mat[2], creator and creator.id or 'nil')) + assert(#items > 0, ('failed to create item: item_type: %s, item_subtype: %s, mat_type: %s, mat_index: %s, unit: %s'):format( + itemType[1], itemType[2], mat[1], mat[2], creator and creator.id or 'nil')) local item = items[1] local mat_token = dfhack.matinfo.decode(item):getToken() quality = math.max(0, math.min(5, quality - 1)) @@ -350,6 +359,12 @@ function hackWish(accessors, opts) end end end + if opts.pos then + for _,item in ipairs(items) do + dfhack.items.moveToGround(item, opts.pos) + end + end + return items end @@ -435,9 +450,4 @@ local accessors = { end, } -local items = hackWish(accessors, {}) -if items and opts.pos then - for _,item in ipairs(items) do - dfhack.items.moveToGround(item, opts.pos) - end -end +hackWish(accessors, {pos=opts.pos}) diff --git a/putontable.lua b/putontable.lua index 072e75171f..ca8d00e5d7 100644 --- a/putontable.lua +++ b/putontable.lua @@ -10,19 +10,21 @@ Arguments: ]====] -local pos=df.global.cursor +local guidm = require('gui.dwarfmode') + local args={...} local doall if args[1]=="-a" or args[1]=="--all" then doall=true end local items={} --as:df.item[] -local build=dfhack.buildings.findAtTile(pos.x,pos.y,pos.z) +local pos = guidm.getCursorPos() +local build = pos and dfhack.buildings.findAtTile(pos.x,pos.y,pos.z) or nil if not df.building_tablest:is_instance(build) then error("No table found at cursor") end for k,v in pairs(df.global.world.items.other.IN_PLAY) do - if pos.x==v.pos.x and pos.y==v.pos.y and pos.z==v.pos.z and v.flags.on_ground then + if v.flags.on_ground and same_xyz(v.pos, pos) then table.insert(items,v) if not doall then break diff --git a/source.lua b/source.lua index ff9305ea32..67d052f95b 100644 --- a/source.lua +++ b/source.lua @@ -1,4 +1,5 @@ --@ module = true +local guidm = require('gui.dwarfmode') local repeatUtil = require('repeat-util') local GLOBAL_KEY = 'source' -- used for state change hooks and persistence @@ -130,11 +131,11 @@ function main(args) return end - local targetPos = copyall(df.global.cursor) + local targetPos = guidm.getCursorPos() local index = find_liquid_source_at_pos(targetPos) if command == 'delete' then - if targetPos.x < 0 then + if not targetPos then qerror("Please place the cursor where there is a source to delete") end if index then @@ -147,7 +148,7 @@ function main(args) end if command == 'add' then - if targetPos.x < 0 then + if not targetPos then qerror('Please place the cursor where you would like a source') end local liquidArg = args[2] diff --git a/stripcaged.lua b/stripcaged.lua index a334daba44..d153d8cda9 100644 --- a/stripcaged.lua +++ b/stripcaged.lua @@ -1,4 +1,5 @@ local argparse = require('argparse') +local guidm = require('gui.dwarfmode') local opts = {} local positionals = argparse.processArgsGetopt({...}, { {'h', 'help', handler = function() opts.help = true end}, @@ -206,8 +207,8 @@ if positionals[2] == 'here' then end end -- Is the player trying to select a cage using the keyboard cursor? - elseif df.global.cursor.z > -10000 then -- cursor has values around -30000 if not valid/active. - local cursor = df.global.cursor + elseif guidm.getCursorPos() then + local cursor = guidm.getCursorPos() for _, cage in ipairs(df.global.world.items.other.ANY_CAGE_OR_TRAP) do if same_xyz(cursor, cage.pos) then table.insert(list, cage) diff --git a/teleport.lua b/teleport.lua index 4a55f6e99b..108f7e8673 100644 --- a/teleport.lua +++ b/teleport.lua @@ -28,6 +28,8 @@ Examples: ]====] +local guidm = require('gui.dwarfmode') + function teleport(unit,pos) dfhack.units.teleport(unit, pos) end @@ -53,12 +55,12 @@ if args.showunitid or args.showpos then if args.showunitid then print(dfhack.gui.getSelectedUnit(true).id) else - printall(df.global.cursor) + printall(guidm.getCursorPos()) end else local unit = tonumber(args.unit) and df.unit.find(tonumber(args.unit)) or dfhack.gui.getSelectedUnit(true) - local pos = not(not args.x or not args.y or not args.z) and {x=args.x,y=args.y,z=args.z} or {x=df.global.cursor.x,y=df.global.cursor.y,z=df.global.cursor.z} + local pos = not(not args.x or not args.y or not args.z) and {x=args.x,y=args.y,z=args.z} or guidm.getCursorPos() if not unit then qerror('A unit needs to be selected or specified. Use teleport -showunitid to get a unit\'s ID.') end - if not pos.x or pos.x==-30000 then qerror('A position needs to be highlighted or specified. Use teleport -showpos to get a position\'s exact xyz values.') end + if not pos then qerror('A position needs to be highlighted or specified. Use teleport -showpos to get a position\'s exact xyz values.') end teleport(unit,pos) end diff --git a/toggle-kbd-cursor.lua b/toggle-kbd-cursor.lua index ae66b1900d..3a9b2b462b 100644 --- a/toggle-kbd-cursor.lua +++ b/toggle-kbd-cursor.lua @@ -1,10 +1,13 @@ local guidm = require('gui.dwarfmode') -local flags = df.global.d_init.feature.flags +if dfhack.world.isAdventureMode() then + qerror('Adventure mode unsupported!') +end +local flags = df.global.d_init.feature.flags if flags.KEYBOARD_CURSOR then flags.KEYBOARD_CURSOR = false - guidm.setCursorPos(xyz2pos(-30000, -30000, -30000)) + guidm.clearCursorPos() print('Keyboard cursor disabled.') else guidm.setCursorPos(guidm.Viewport.get():getCenter()) From 30af7c95317613884078d2b82e6f3d2d6e5c4881 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:32:52 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- gui/tiletypes.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/tiletypes.lua b/gui/tiletypes.lua index 513fd9181c..708359ba57 100644 --- a/gui/tiletypes.lua +++ b/gui/tiletypes.lua @@ -768,7 +768,7 @@ function BoxSelection:onInput(keys) local mousePos = dfhack.gui.getMousePos(true) local cursorPos = guidm.getCursorPos() - + if cursorPos and keys.SELECT then cursorPos.x = math.max(math.min(cursorPos.x, df.global.world.map.x_count - 1), 0) cursorPos.y = math.max(math.min(cursorPos.y, df.global.world.map.y_count - 1), 0) From 971ae8378f5e0ad00f894a0d7d08cc97b32af823 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 12 Feb 2025 21:24:47 -0800 Subject: [PATCH 3/6] Make toggle-kbd-cursor work with adv mode * Update toggle-kbd-cursor.lua * Update toggle-kbd-cursor.rst * Update changelog.txt --- changelog.txt | 3 +-- docs/toggle-kbd-cursor.rst | 6 +++--- toggle-kbd-cursor.lua | 25 ++++++++++++++----------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/changelog.txt b/changelog.txt index 38d56e424d..cef1f1948a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -38,10 +38,9 @@ Template for new versions: ## Fixes - `position`: support for adv mode look cursor -- `devel/query`, `devel/tree-info`, `hfs-pit`, `colonies`: now function in adventure mode +- `devel/query`, `devel/tree-info`, `hfs-pit`, `colonies`, `toggle-kbd-cursor`: now function in adventure mode - `hfs-pit`: fix up tiletypes of pit walls, better placement of stairs (w/r/t eerie pits and ramp tops) - `modtools/create-item`: ``hackWish`` now respects ``opts.pos`` and will spawn items there if provided -- `toggle-kbd-cursor`: exclude adventure mode because it isn't compatible ## Misc Improvements - `hide-tutorials`: handle tutorial popups for adventure mode diff --git a/docs/toggle-kbd-cursor.rst b/docs/toggle-kbd-cursor.rst index aba577aceb..4ae0e588d7 100644 --- a/docs/toggle-kbd-cursor.rst +++ b/docs/toggle-kbd-cursor.rst @@ -3,14 +3,14 @@ toggle-kbd-cursor .. dfhack-tool:: :summary: Toggles the keyboard cursor. - :tags: fort interface + :tags: adventure fort interface This tool simply toggles the keyboard cursor so you can quickly switch it on when you need it. Many other tools, like `autodump`, need a keyboard cursor for selecting a target tile. Note that you'll still need to enter an interface mode where the keyboard cursor is visible, like mining mode or dumping mode, in -order to use the cursor. This tool does not function in adventure mode because -the adventurer cursor cannot be trivially toggled. +order to use the cursor. In adventure mode, this tool toggles look mode via +simulated input. Usage ----- diff --git a/toggle-kbd-cursor.lua b/toggle-kbd-cursor.lua index 3a9b2b462b..3033049dbe 100644 --- a/toggle-kbd-cursor.lua +++ b/toggle-kbd-cursor.lua @@ -1,16 +1,19 @@ +local gui = require('gui') local guidm = require('gui.dwarfmode') if dfhack.world.isAdventureMode() then - qerror('Adventure mode unsupported!') -end - -local flags = df.global.d_init.feature.flags -if flags.KEYBOARD_CURSOR then - flags.KEYBOARD_CURSOR = false - guidm.clearCursorPos() - print('Keyboard cursor disabled.') + local open = df.global.game.main_interface.adventure.look.open + gui.simulateInput(dfhack.gui.getDFViewscreen(), open and 'LEAVESCREEN' or 'A_LOOK') + print('Look mode '..(open and 'disabled.' or 'enabled.')) else - guidm.setCursorPos(guidm.Viewport.get():getCenter()) - flags.KEYBOARD_CURSOR = true - print('Keyboard cursor enabled.') + local flags = df.global.d_init.feature.flags + if flags.KEYBOARD_CURSOR then + flags.KEYBOARD_CURSOR = false + guidm.clearCursorPos() + print('Keyboard cursor disabled.') + else + guidm.setCursorPos(guidm.Viewport.get():getCenter()) + flags.KEYBOARD_CURSOR = true + print('Keyboard cursor enabled.') + end end From ab2a0ed72e23088412a8372346648993b154aedb Mon Sep 17 00:00:00 2001 From: Myk Date: Fri, 7 Mar 2025 16:11:06 -0800 Subject: [PATCH 4/6] changelog reorg --- changelog.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/changelog.txt b/changelog.txt index cef1f1948a..4c2684d404 100644 --- a/changelog.txt +++ b/changelog.txt @@ -30,17 +30,20 @@ Template for new versions: - `devel/export-map`: export map tile data to a JSON file - `autocheese`: automatically make cheese using barrels that have accumulated sufficient milk - `gui/spectate`: interactive UI for configuring `spectate` -- `launch`: (reinstated) thrash your enemies with a flying suplex -- `putontable`: (reinstated) make an item appear on a table like in adventure mode +- `launch`: (reinstated) new adventurer fighting move: thrash your enemies with a flying suplex +- `putontable`: (reinstated) make an item appear on a table +- `devel/query`: support adventure mode +- `devel/tree-info`: support adventure mode +- `hfs-pit`: support adventure mode +- `colonies`: support adventure mode +- `toggle-kbd-cursor`: support adventure mode ## New Features - `advtools`: new ``advtools.fastcombat`` overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys ## Fixes - `position`: support for adv mode look cursor -- `devel/query`, `devel/tree-info`, `hfs-pit`, `colonies`, `toggle-kbd-cursor`: now function in adventure mode -- `hfs-pit`: fix up tiletypes of pit walls, better placement of stairs (w/r/t eerie pits and ramp tops) -- `modtools/create-item`: ``hackWish`` now respects ``opts.pos`` and will spawn items there if provided +- `hfs-pit`: use correct wall types when making pits with walls ## Misc Improvements - `hide-tutorials`: handle tutorial popups for adventure mode @@ -49,6 +52,8 @@ Template for new versions: - `gui/confirm`: in the delete manager order confirmation dialog, show a description of which order you have selected to delete - `position`: display both adventurer and site pos simultaneously. Display map block pos+offset of selected tile. - `gui/create-item`: now accepts a ``pos`` argument of where to spawn items +- `modtools/create-item`: exported ``hackWish`` function now supports ``opts.pos`` for determining spawn location +- `hfs-pit`: improve placement of stairs w/r/t eerie pits and ramp tops ## Removed From ecb2f96257249cf495cebc93eb29b0e00e087e94 Mon Sep 17 00:00:00 2001 From: Myk Date: Fri, 7 Mar 2025 16:11:44 -0800 Subject: [PATCH 5/6] don't change type of var --- devel/tree-info.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/devel/tree-info.lua b/devel/tree-info.lua index d4d23b0c55..ec59563de0 100644 --- a/devel/tree-info.lua +++ b/devel/tree-info.lua @@ -173,11 +173,9 @@ function printTree(t) end if not dfhack_flags.module then - local p = guidm.getCursorPos() - if not p then - qerror('No cursor!') - end - p = dfhack.maps.getPlantAtTile(p) + local pos = guidm.getCursorPos() + if not pos then qerror('No cursor!') end + local p = dfhack.maps.getPlantAtTile(pos) if p and p.tree_info then printTree(p.tree_info) else From c5d2495ba28d7493db8c35e508d9c07086aa149b Mon Sep 17 00:00:00 2001 From: Myk Date: Fri, 7 Mar 2025 16:12:02 -0800 Subject: [PATCH 6/6] reword toggle-kbd-cursor docs --- docs/toggle-kbd-cursor.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/toggle-kbd-cursor.rst b/docs/toggle-kbd-cursor.rst index 4ae0e588d7..3f5b3f2996 100644 --- a/docs/toggle-kbd-cursor.rst +++ b/docs/toggle-kbd-cursor.rst @@ -5,12 +5,15 @@ toggle-kbd-cursor :summary: Toggles the keyboard cursor. :tags: adventure fort interface -This tool simply toggles the keyboard cursor so you can quickly switch it on -when you need it. Many other tools, like `autodump`, need a keyboard cursor for -selecting a target tile. Note that you'll still need to enter an interface mode -where the keyboard cursor is visible, like mining mode or dumping mode, in -order to use the cursor. In adventure mode, this tool toggles look mode via -simulated input. +This tool toggles the keyboard cursor so you can quickly switch it on when +you need it. Many other DFHack tools, like `autodump` or `digv`, need a +keyboard cursor for selecting a target tile. + +In fort mode, it toggles the game setting for "Enable keyboard cursor". +Note that you'll still need to enter an interface mode where the keyboard +cursor is visible, like mining mode or dumping mode. + +In adventure mode, it will toggle "Look" mode. Usage -----