Here is some more of that CthuLua stuff. This version dispenses with the calibration step thanks to lethosor's help. It also reports the Z level as it shows on the screen instead of the internal offset, and now does sanity checks on your goto coordinates.
Unfortunately, fixing the Z broke compatibility with bookmarks from the previous version. Hopefully those were only used in test forts.
-- bookmark script v1.01
-- Set and clears persistent bookmarks on the fort map.
-- Enter "bookmark help" for a list of reserved names.
-- Version 1.01 removes the need for the "calibrate" step and harmonizes reported Z with screen display.
local args = {...}
local bookmarks = dfhack.persistent.get_all("BOOKMARK",true)
if args[1] == "help" then
print([[bookmark.lua
Enter "bookmark foo" to create a bookmark named "foo" at the current location.
Any one-word string may be used except the following reserved words:
"bookmark help" prints this command summary.
"bookmark list" prints a list of existing bookmarks.
"bookmark drop foo" erases the bookmark named "foo".
"bookmark clear all" erases all current bookmarks, note the space between "clear" and "all".
]])
elseif args[1] == "list" then
if bookmarks then
for _, bookmark in ipairs(bookmarks) do
print(bookmark.value .. ": " .. bookmark.ints[1] .. " " .. bookmark.ints[2] .. " " .. bookmark.ints[3])
end
else
print("No bookmarks defined.")
end
elseif args[1] == "clear" and args[2] == "all" then
if bookmarks then
local count = #bookmarks
for _, bookmark in ipairs(bookmarks) do
bookmark:delete()
end
print("Deleted " .. count .. " bookmarks.")
else
print("No bookmarks are defined, so no action taken.")
end
elseif args[1] == "drop" and args[2] then
if bookmarks then
local del = false
for _, bookmark in ipairs(bookmarks) do
if bookmark.value == args[2] then
bookmark:delete()
print("Bookmark " .. args[2] .. " deleted.")
del = true
end
end
if del == false then print("Bookmark " .. args[2] .. " not defined, so no action taken.") end
else
print("No bookmarks are defined, so no action taken.")
end
elseif args[1] and not args[2] then
local pos = {}
pos = copyall(df.global.cursor)
pos.z = pos.z + df.global.world.map.region_z
local make_new = true
if pos.x == -30000 then
name = "Center:"
dm = require('gui.dwarfmode')
pos["x"] = df.global.window_x + math.floor(dm.getPanelLayout().map.width / 2)
pos["y"] = df.global.window_y + math.floor(dm.getPanelLayout().map.height / 2)
pos["z"] = df.global.window_z + df.global.world.map.region_z
end
if bookmarks then
for _, bookmark in ipairs(bookmarks) do
if bookmark.value == args[1] then
bookmark.ints[1] = pos.x
bookmark.ints[2] = pos.y
bookmark.ints[3] = pos.z
bookmark:save()
print("Bookmark " .. args[1] .. " updated.")
make_new = false
end
end
if make_new == true then
dfhack.persistent.save({key="BOOKMARK/"..args[1],value=args[1],ints={pos.x,pos.y,pos.z}})
print("Bookmark " .. args[1] .. " created.")
end
else
dfhack.persistent.save({key="BOOKMARK/"..args[1],value=args[1],ints={pos.x,pos.y,pos.z}})
print("Bookmark " .. args[1] .. " created.")
end
else
print([[
Invalid command. Use "bookmark help" for help.
]])
end
-- goto script v1.01
-- Move the screen to a bookmark or a set of XYZ coordinates.
-- Enter "bookmark help" for a list of reserved names.
-- Version 1.01 removes the need for the "calibrate" step, harmonizes reported Z with screen display, and checks bounds on target coordinates.
local args = {...}
local bookmarks = dfhack.persistent.get_all("BOOKMARK",true)
if args[1] == "help" then
print([[bookmark.lua
Enter "goto # # #" to move the screen to a set of XYZ coordinates.
Enter "goto foo" to move the screen to be centered on bookmark "foo".
"goto help" prints this command summary.
]])
elseif args[1] and not args[2] then
if bookmarks then
local pos = {}
local xcoord = df.global.cursor.x
for _, bookmark in ipairs(bookmarks) do
if bookmark.value == args[1] then
pos["x"] = bookmark.ints[1]
pos["y"] = bookmark.ints[2]
pos["z"] = bookmark.ints[3]
end
end
if pos.x then
dm = require('gui.dwarfmode')
if xcoord ~= -30000 then df.global.cursor.x = pos.x end
df.global.cursor.y = pos.y
df.global.cursor.z = pos.z - df.global.world.map.region_z
df.global.window_x = math.max(pos.x - math.floor(dm.getPanelLayout().map.width / 2), 0)
df.global.window_y = math.max(pos.y - math.floor(dm.getPanelLayout().map.height / 2), 0)
df.global.window_z = pos.z - df.global.world.map.region_z
print("Now at " .. args[1])
else
print("Bookmark " .. args[1] .. " not defined.")
end
else
print("No bookmarks defined.")
end
elseif args[1] and args[2] and args[3] then
local pos_x = tonumber(args[1])
local pos_y = tonumber(args[2])
local pos_z = tonumber(args[3]) - df.global.world.map.region_z
local max_x = df.global.world.map.x_count - 1
local max_y = df.global.world.map.y_count - 1
local max_z = df.global.world.map.z_count - 1
if pos_x > max_x or pos_y > max_y or pos_z > max_z or pos_x < 0 or pos_y < 0 or pos_z < 0 then
print("Target out of range.")
else
local dm = require('gui.dwarfmode')
local size_x = dm.getPanelLayout().map.width
local size_y = dm.getPanelLayout().map.height
local half_x = math.floor(size_x / 2)
local half_y = math.floor(size_y / 2)
local window_x = math.min(math.max(pos_x - half_x, 0), max_x - size_x)
local window_y = math.min(math.max(pos_y - half_y, 0), max_y - size_y)
local xcoord = df.global.cursor.x
if xcoord ~= -30000 then
df.global.cursor.x = pos_x
df.global.cursor.y = pos_y
else
df.global.cursor.y = window_y + half_y
end
df.global.cursor.z = pos_z
df.global.window_x = window_x
df.global.window_y = window_y
df.global.window_z = pos_z
if xcoord == -30000 and (pos_x ~= window_x + half_x or pos_y ~= window_y + half_y) then
print("Too close to edge. Now at " .. window_x + half_x .. " " .. window_y + half_y .. " " .. pos_z + df.global.world.map.region_z)
else
print("Now at " .. pos_x .. " " .. pos_y .. " " .. pos_z + df.global.world.map.region_z)
end
end
else
print([[
Invalid command. Use "goto help" for help.
]])
end
-- whereami script v1.01
-- Reports coordinates of the cursor if it is present, or the center of the screen if not.
-- Also lists any bookmarks set for these coordinates.
-- Version 1.01 removes the need for the "calibrate" step and harmonizes reported Z with screen display.
local bookmarks = dfhack.persistent.get_all("BOOKMARK",true)
local pos = {}
pos = copyall(df.global.cursor)
pos.z = pos.z + df.global.world.map.region_z
local name = "Cursor:"
if pos.x == -30000 then
dm = require('gui.dwarfmode')
name = "Center:"
pos["x"] = df.global.window_x + math.floor(dm.getPanelLayout().map.width / 2)
pos["y"] = df.global.window_y + math.floor(dm.getPanelLayout().map.height / 2)
pos["z"] = df.global.window_z + df.global.world.map.region_z
end
print(name .. " " .. pos.x .. " " .. pos.y .. " " .. pos.z)
if bookmarks then
for _, bookmark in ipairs(bookmarks) do
if bookmark.ints[1] == pos.x and bookmark.ints[2] == pos.y and bookmark.ints[3] == pos.z then
print("Bookmarked as " .. bookmark.value)
end
end
end