Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ Template for new versions:
- `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

## Misc Improvements
- `hide-tutorials`: handle tutorial popups for adventure mode
- `hide-tutorials`: new ``reset`` command that will re-enable popups in the current game (in case you hid them all and now want them back)
- `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.

## Removed

Expand Down
2 changes: 1 addition & 1 deletion docs/position.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ position
This tool reports the current date, clock time, month, season, and historical
era. It also reports the keyboard cursor position (or just the z-level if no
active cursor), window size, and mouse location on the screen. If a site is
loaded, it prints the world coordinates of the site. If not, it prints the world
loaded, it prints the world coordinates of the site. It also prints the world
coordinates of the adventurer (if applicable).

Can also be used to copy the current keyboard cursor position for later use.
Expand Down
161 changes: 100 additions & 61 deletions position.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
-- Report cursor and mouse position, along with other info.
--@ module = true

local cursor = df.global.cursor
local args = {...}
if #args > 0 then --Copy keyboard cursor to clipboard
if #args > 1 then
qerror('Too many arguments!')
elseif args[1] ~= '-c' and args[1] ~= '--copy' then
qerror('Invalid argument "'..args[1]..'"!')
elseif cursor.x < 0 then
qerror('No keyboard cursor!')
local argparse = require('argparse')
local guidm = require('gui.dwarfmode')

local function parse_args(args)
local opts = {}
local positionals = argparse.processArgsGetopt(args,
{
{'c', 'copy', handler=function() opts.copy = true end},
})

if #positionals > 0 then
qerror('Too many positionals!')
end

dfhack.internal.setClipboardTextCp437(('%d,%d,%d'):format(cursor.x, cursor.y, cursor.z))
return
return opts
end

local months = {
local months =
{
'Granite, in early Spring.',
'Slate, in mid Spring.',
'Felsite, in late Spring.',
Expand All @@ -29,68 +34,102 @@ local months = {
'Obsidian, in late Winter.',
}

--Fortress mode counts 1200 ticks per day and 403200 per year
--Adventurer mode counts 86400 ticks to a day and 29030400 ticks per year
--Twelve months per year, 28 days to every month, 336 days per year
function print_time_info()
--Fortress mode counts 1200 ticks per day and 403200 per year
--Adventurer mode counts 86400 ticks to a day and 29030400 ticks per year
--Twelve months per year, 28 days to every month, 336 days per year
local julian_day = df.global.cur_year_tick // 1200 + 1
local month = julian_day // 28 + 1 --days and months are 1-indexed
local day = julian_day % 28

local julian_day = df.global.cur_year_tick // 1200 + 1
local month = julian_day // 28 + 1 --days and months are 1-indexed
local day = julian_day % 28
local time_of_day = df.global.cur_year_tick_advmode // 336
local second = time_of_day % 60
local minute = time_of_day // 60 % 60
local hour = time_of_day // 3600 % 24

local time_of_day = df.global.cur_year_tick_advmode // 336
local second = time_of_day % 60
local minute = time_of_day // 60 % 60
local hour = time_of_day // 3600 % 24
print('Time:')
print((' The time is %02d:%02d:%02d'):format(hour, minute, second))
print((' The date is %03d-%02d-%02d'):format(df.global.cur_year, month, day))
print(' It is the month of '..months[month])

print('Time:')
print((' The time is %02d:%02d:%02d'):format(hour, minute, second))
print((' The date is %03d-%02d-%02d'):format(df.global.cur_year, month, day))
print(' It is the month of '..months[month])
local eras = df.global.world.history.eras
if #eras > 0 then
print(' It is the '..eras[#eras-1].title.name..'.')
end
end

local eras = df.global.world.history.eras
if #eras > 0 then
print(' It is the '..eras[#eras-1].title.name..'.')
function get_adv_region_pos() --Regional coords
if not dfhack.world.getAdventurer() then --Army exists when unit doesn't
local army = df.army.find(df.global.adventure.player_army_id)
if army then
return army.pos.x//48, army.pos.y//48
end
end
local wd = df.global.world.world_data
return wd.midmap_data.adv_region_x, wd.midmap_data.adv_region_y
end

print('Place:')
print(' The z-level is z='..df.global.window_z)
local function print_world_info()
local wd = df.global.world.world_data
local site = dfhack.world.getCurrentSite()
if site then
print((' The current site is at x=%d, y=%d on the %dx%d world map.'):
format(site.pos.x, site.pos.y, wd.world_width, wd.world_height))
end

if cursor.x < 0 then
print(' The keyboard cursor is inactive.')
else
print(' The keyboard cursor is at x='..cursor.x..', y='..cursor.y)
if dfhack.world.isAdventureMode() then
local x, y = get_adv_region_pos()
print((' The adventurer is at x=%d, y=%d on the %dx%d world map.'):
format(x, y, wd.world_width, wd.world_height))
end
end

local x, y = dfhack.screen.getWindowSize()
print(' The window is '..x..' tiles wide and '..y..' tiles high.')
function print_place_info(cursor)
print('Place:')
print(' The z-level is z='..df.global.window_z)

x, y = dfhack.screen.getMousePos()
if x then
print(' The mouse is at x='..x..', y='..y..' within the window.')
local pos = dfhack.gui.getMousePos()
if pos then
print(' The mouse is over map tile x='..pos.x..', y='..pos.y)
if cursor then
local x, y = cursor.x, cursor.y
print((' The keyboard cursor is at x=%d, y=%d (%d+%d, %d+%d)'):
format(x, y, x//16*16, x%16, y//16*16, y%16))
else
print(' The keyboard cursor is inactive.')
end
else
print(' The mouse is not in the DF window.')
end

local wd = df.global.world.world_data
local site = dfhack.world.getCurrentSite()
if site then
print((' The current site is at x=%d, y=%d on the %dx%d world map.'):
format(site.pos.x, site.pos.y, wd.world_width, wd.world_height))
elseif dfhack.world.isAdventureMode() then
x, y = -1, -1
for _,army in ipairs(df.global.world.armies.all) do
if army.flags.player then
x, y = army.pos.x // 48, army.pos.y // 48
break
local x, y = dfhack.screen.getWindowSize()
print(' The window is '..x..' tiles wide and '..y..' tiles high.')

x, y = dfhack.screen.getMousePos()
if x then
print(' The mouse is at x='..x..', y='..y..' within the window.')
local pos = dfhack.gui.getMousePos()
if pos then
print(' The mouse is over map tile x='..pos.x..', y='..pos.y)
end
else
print(' The mouse is not in the DF window.')
end
if x < 0 then
x, y = wd.midmap_data.adv_region_x, wd.midmap_data.adv_region_y

print_world_info()
end

if dfhack_flags.module then
return
end

function main(opts)
local cursor = guidm.getCursorPos()

if opts.copy then --Copy keyboard cursor to clipboard
if not cursor then
qerror('No keyboard cursor!')
end
dfhack.internal.setClipboardTextCp437(('%d,%d,%d'):format(cursor.x, cursor.y, cursor.z))
return --Don't print anything
end
print((' The adventurer is at x=%d, y=%d on the %dx%d world map.'):
format(x, y, wd.world_width, wd.world_height))

print_time_info()
print_place_info(cursor)
end

main(parse_args({...}))