Here's something.
-- -p {x,y,z} for coordinates, -h for help text. No args for default
NO_DIRECTION = '--------'
ALL_MATS_ALLOWED = false
HELP_TEXT = '-p {x,y,z} for coordinates, -h for help text. No args for default'
--Note that way the configuration is formatted below. Its unconventional, but its more familiar.
--Also note that we are using 'empty' for tiles we don't want to change
DEFAULT_CONFIGURATION =
{
--this represents a z,y,x format. This very closely resembes the Z-level format. This will be used. Note that the lowest Z-level shown first.
{--z level 1
--the outer {} represents the y, the inner the x
{df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL}, --y1
{df.tiletype_shape.WALL, df.tiletype_shape.FLOOR, df.tiletype_shape.FLOOR, df.tiletype_shape.FLOOR, df.tiletype_shape.WALL}, --y2
{df.tiletype_shape.WALL, df.tiletype_shape.FLOOR, df.tiletype_shape.STAIR_UP, df.tiletype_shape.FLOOR, df.tiletype_shape.WALL}, --y3
{df.tiletype_shape.WALL, df.tiletype_shape.FLOOR, df.tiletype_shape.FLOOR, df.tiletype_shape.FLOOR, df.tiletype_shape.WALL},
{df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL, df.tiletype_shape.WALL}
},
{ --z level 2
{'empty', 'empty', 'empty', 'empty', 'empty'},
{'empty', 'empty', 'empty', 'empty', 'empty'},
{'empty', 'empty', df.tiletype_shape.STAIR_DOWN, 'empty', 'empty'},
{'empty', 'empty', 'empty', 'empty', 'empty'},
{'empty', 'empty', 'empty', 'empty', 'empty'}
}
}
-- this method is carelessly stolen from Kurik Amudnil's magic shovel
-- Kurik Amudnil, Thank you, it provides a novel way to get the tile I want in a Lua script.
function findTileType(shape, material, variant, special, dir)
local tt_attrs
--print(shape .. ' ' .. material)
for tt=0,698 do
tt_attrs = df.tiletype.attrs[tt]
if shape ~= df.tiletype_shape.NONE and shape ~= tt_attrs.shape then
--continue
elseif material ~= df.tiletype_material.NONE and material ~= tt_attrs.material then
--continue
-- Don't require variant to match if the destination tile doesn't even have one
elseif variant ~= df.tiletype_variant.NONE and variant ~= tt_attrs.variant and
tt_attrs.variant ~= df.tiletype_variant.NONE then
--continue
-- Same for special
elseif special ~= df.tiletype_special.NONE and special ~= tt_attrs.special and
tt_attrs.special ~= df.tiletype_special.NONE then
--continue
elseif dir ~= NO_DIRECTION and dir ~= tt_attrs.direction then -- if (tdir && tdir != tileDirection(tt)),
--continue
else
--Match
return tt
end
end
print('tile type not found')
return df.tiletype.Void
end
--configuraion is a multidimensional array
--of a room, such as floor, wall, up stair, down stair, or up/down stair.
--Ramps not supported yet.
--configuration should hold a tiletype_shape, ex: df.tiletype_shape.FLOOR
--In this manner, we can control the configuration of the room
--A hardcoded configuration will be provided as an example.
function DigRoom(configuration, absX, absY, absZ)
local shape, material, variant, special, dir
--damn indexing from 1 convention...
for relZ = 1, #configuration do
print(relZ .. ' ' .. #configuration)
for relY = 1, #configuration[relZ] do
print(relY .. ' ' .. #configuration[relZ])
for relX = 1, #configuration[relZ][relY] do
print(relX .. ' ' .. #configuration[relZ][relY])
--print('x: ' .. relX .. ' y: ' .. relY .. ' z: ' .. relZ)
if configuration[relZ][relY][relX] ~= nil and configuration[relZ][relY][relX] ~= 'empty' then
--print('Shape acquired for x: ' .. relX .. ' y: ' .. relY .. ' z: ' .. relZ)
shape = configuration[relZ][relY][relX] --set the shape of the tile from configuration
material = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-1, relY+absY-1, relZ+absZ-1)].material --get the material of the tile
variant = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-1, relY+absY-1, relZ+absZ-1)].variant
special = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-1, relY+absY-1, relZ+absZ-1)].special
dir = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-1, relY+absY-1, relZ+absZ-1)].direction
if shape == df.tiletype_shape.FLOOR then
variant = math.random(0,3)
special = df.tiletype_special.NORMAL
end
dir = NO_DIRECTION
if material == df.tiletype_material.SOIL or material == df.tiletype_material.GRASS_LIGHT or
material == df.tiletype_material.GRASS_DARK or material == df.tiletype_material.GRASS_DRY or
material == df.tiletype_material.GRASS_DEAD or material == df.tiletype_material.PLANT or
material == df.tiletype_material.AIR or ALL_MATS_ALLOWED then
local tt = findTileType(shape, material, variant, special, dir)
--print(tt)
if tt ~= df.tiletype.Void then
local effX = relX+absX-1
local effY = relY+absY-1
local effZ = relZ+absZ-1
--print('effX: ' .. effX .. ' effY: ' .. effY .. ' effZ: ' .. effZ .. ' effX%16: ' .. effX%16 .. ' effY%16: ' .. effY%16)
dfhack.maps.getTileBlock(effX, effY, effZ).tiletype[effX%16][effY%16] = tt
end
end
else
--print('nothing done')
end
end
end
end
end
local args={...}
if args == nil then
--TEST()
else
local position --an array holding x,y,z coordinates
local configuration --an array holding the configuration to be dug
local skip = false --to skip the next argument, or not to
local help = false --asking for help?
for i = 1, #args do
if not skip then
if args[i] == '-p' or args[i] == '--position' then
position = args[i+1]
skip = true
elseif args[i] == '-c' or args[i] == '--configuration' then
configuration = args[i+1]
skip = true
elseif args[i] == '-h' or args[i] == '--help' then
print(HELP_TEXT)
help = true
break
end
end
skip = false
end
if not help then
if position == nil then
position = {df.global.cursor.x, df.global.cursor.y, df.global.cursor.z}
end
if configuration == nil or true then
configuration = DEFAULT_CONFIGURATION
end
DigRoom(configuration, position[1], position[2], position[3])
end
end
It currently only mines out soil, but that can be toggled by ALL_MATS_ALLOWED.
I originally had it so that you could define your own "configuration" and pass it in with -c, but it didn't seem to work. For now, edit the default configuration, and it should be simple to define several, add an argument, and use the appropriate configuration based on that argument.
Do note that the "configuration" is defined oddly. By formatting it z,y,x rather than x,y,z it appears similar to diagrams people draw in ASCII. Also, it currently only supports stairs, floor, and wall. It may be able to do others, but I'd advise against it, and ramps won't work. Also, when defining your own configuration, for the love of god don't use nil to define an unchanged tile, use 'empty', because nil will mess with detecting the size, then you have to define the size rather than detect it automatically. And since the size can be detected, you should be able to define jagged arrays. I haven't tested that, but it should work.