first stage of blueprint overhaul
- make depth and name parameters optional - allow depth to be negative to indicate top-down instead of the previous hard-coded bottom-up - add --cursor for specifying start position (game cursor is not needed if this param is specified)develop
parent
84a1b39daa
commit
a7a5a48c7a
@ -1,14 +1,169 @@
|
||||
local _ENV = mkmodule('plugins.blueprint')
|
||||
|
||||
--[[
|
||||
local utils = require('utils')
|
||||
|
||||
Native functions:
|
||||
-- the info here is very basic and minimal, so hopefully we won't need to change
|
||||
-- it when features are added and the full blueprint docs in Plugins.rst are
|
||||
-- updated.
|
||||
local help_text =
|
||||
[=[
|
||||
|
||||
* dig(start, end, name)
|
||||
* build(start, end, name)
|
||||
* place(start, end, name)
|
||||
* query(start, end, name)
|
||||
blueprint
|
||||
=========
|
||||
|
||||
--]]
|
||||
Records the structure of a portion of your fortress in quickfort blueprints.
|
||||
|
||||
Usage:
|
||||
|
||||
blueprint <width> <height> [<depth>] [<name> [<phases>]] [<options>]
|
||||
blueprint gui [<name> [<phases>]] [<options>]
|
||||
|
||||
Examples:
|
||||
|
||||
blueprint gui
|
||||
Runs gui/blueprint, the interactive blueprint frontend, where all
|
||||
configuration can be set visually and interactively.
|
||||
|
||||
blueprint 30 40 bedrooms
|
||||
Generates blueprints for an area 30 tiles wide by 40 tiles tall, starting
|
||||
from the active cursor on the current z-level. Output is written to the
|
||||
"bedrooms.csv" file in the "blueprints" directory.
|
||||
|
||||
See the online DFHack documentation for more examples and details.
|
||||
]=]
|
||||
|
||||
valid_phases = utils.invert{
|
||||
'dig',
|
||||
'build',
|
||||
'place',
|
||||
'query',
|
||||
}
|
||||
|
||||
function print_help()
|
||||
print(help_text)
|
||||
end
|
||||
|
||||
local function parse_cursor(opts, arg)
|
||||
local _, _, x, y, z = arg:find('^(%d+),(%d+),(%d+)$')
|
||||
if not x then
|
||||
qerror(('invalid argument for --cursor option: "%s"; expected format' ..
|
||||
' is "<x>,<y>,<z>", for example: "30,60,150"'):format(arg))
|
||||
end
|
||||
-- be careful not to replace struct members when called from C++, but also
|
||||
-- create the table as needed when called from lua
|
||||
if not opts.start then opts.start = {} end
|
||||
opts.start.x = tonumber(x)
|
||||
opts.start.y = tonumber(y)
|
||||
opts.start.z = tonumber(z)
|
||||
end
|
||||
|
||||
-- dimension must be a non-nil integer that is >= 1 (or at least non-zero if
|
||||
-- negative_ok is true)
|
||||
local function is_bad_dim(dim, negative_ok)
|
||||
return not dim
|
||||
or (not negative_ok and dim < 1 or dim == 0)
|
||||
or dim ~= math.floor(dim)
|
||||
end
|
||||
|
||||
local function parse_positionals(opts, args, start_argidx)
|
||||
local argidx = start_argidx
|
||||
|
||||
-- set defaults
|
||||
opts.name, opts.auto_phase = 'blueprint', true
|
||||
|
||||
local name = args[argidx]
|
||||
if not name then return end
|
||||
if name == '' then
|
||||
qerror(('invalid basename: "%s"; must be a valid, non-empty pathname')
|
||||
:format(args[argidx]))
|
||||
end
|
||||
argidx = argidx + 1
|
||||
-- normalize paths to forward slashes
|
||||
opts.name = name:gsub(package.config:sub(1,1), "/")
|
||||
|
||||
local auto_phase = true
|
||||
local phase = args[argidx]
|
||||
while phase do
|
||||
if valid_phases[phase] then
|
||||
auto_phase = false
|
||||
opts[phase] = true
|
||||
end
|
||||
argidx = argidx + 1
|
||||
phase = args[argidx]
|
||||
end
|
||||
opts.auto_phase = auto_phase
|
||||
end
|
||||
|
||||
local function process_args(opts, args)
|
||||
if args[1] == 'help' then
|
||||
opts.help = true
|
||||
return
|
||||
end
|
||||
|
||||
return utils.processArgsGetopt(args, {
|
||||
{'c', 'cursor', hasArg=true,
|
||||
handler=function(optarg) parse_cursor(opts, optarg) end},
|
||||
{'h', 'help', handler=function() opts.help = true end},
|
||||
})
|
||||
end
|
||||
|
||||
function parse_gui_commandline(opts, args)
|
||||
local positionals = process_args(opts, args)
|
||||
if opts.help then return end
|
||||
parse_positionals(opts, positionals, 1)
|
||||
end
|
||||
|
||||
function parse_commandline(opts, ...)
|
||||
local positionals = process_args(opts, {...})
|
||||
if opts.help then return end
|
||||
|
||||
local width, height = tonumber(positionals[1]), tonumber(positionals[2])
|
||||
if is_bad_dim(width) or is_bad_dim(height) then
|
||||
qerror(('invalid width and height: "%s" "%s"; width and height must' ..
|
||||
' be positive integers'):format(positionals[1], positionals[2]))
|
||||
end
|
||||
opts.width, opts.height, opts.depth = width, height, 1
|
||||
|
||||
local depth = tonumber(positionals[3])
|
||||
if depth then
|
||||
if is_bad_dim(depth, true) then
|
||||
qerror(('invalid depth: "%s"; must be a non-zero integer')
|
||||
:format(positionals[3]))
|
||||
end
|
||||
opts.depth = depth
|
||||
end
|
||||
|
||||
parse_positionals(opts, positionals, depth and 4 or 3)
|
||||
end
|
||||
|
||||
function do_gui(command, ...)
|
||||
local args = {...}
|
||||
print('launching gui/blueprint')
|
||||
dfhack.timeout(1, 'frames',
|
||||
function() dfhack.run_script('gui/blueprint',
|
||||
table.unpack(args)) end)
|
||||
end
|
||||
|
||||
-- compatibility with old exported API. we route the request back through
|
||||
-- run_command so we have a unified path for parameter processing and invariant
|
||||
-- checking.
|
||||
local function do_blueprint(start_pos, end_pos, name, phase)
|
||||
local width = math.abs(start_pos.x - end_pos.x) + 1
|
||||
local height = math.abs(start_pos.y - end_pos.y) + 1
|
||||
local depth = math.abs(start_pos.z - end_pos.z) + 1
|
||||
if start_pos.z > end_pos.z then depth = -depth end
|
||||
|
||||
local x = math.min(start_pos.x, end_pos.x)
|
||||
local y = math.min(start_pos.y, end_pos.y)
|
||||
local z = start_pos.z
|
||||
|
||||
local cursor = ('--cursor=%d,%d,%d'):format(x, y, z)
|
||||
|
||||
return dfhack.run_command{'blueprint',
|
||||
width, height, depth, name, phase, cursor}
|
||||
end
|
||||
for phase in pairs(valid_phases) do
|
||||
_ENV[phase] = function(s, e, n) do_blueprint(s, e, n, phase) end
|
||||
end
|
||||
|
||||
return _ENV
|
||||
|
Loading…
Reference in New Issue