Hey guys,
I do have a script that digs rooms + up/downstairs into soil levels only, which is really neat for kobolds, but I do encounter two issues with it:
1. It works when called from dfhack and I have a cursor position, but not when triggered by a unit in a workshop. I assume that the worker-as-position is not in the script, which should be easy to fix (?).
2. The newly-dug room is hidden, it's still unrevealed. I can show it by running 'revflood', but that always takes a lot of time to run. It would be more efficient if the script itself would reveal the tiles it digs.
Can anyone have a look and let me know what can be done?
DigRoom.lua
-- -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 resembles 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.STAIR_UP, df.tiletype_shape.FLOOR, 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', df.tiletype_shape.STAIR_DOWN, 'empty', '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-2, relY+absY-2, relZ+absZ-2)].material --get the material of the tile
variant = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-2, relY+absY-2, relZ+absZ-2)].variant
special = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-2, relY+absY-2, relZ+absZ-2)].special
dir = df.tiletype.attrs[dfhack.maps.getTileType(relX+absX-2, relY+absY-2, relZ+absZ-2)].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-2
local effY = relY+absY-2
local effZ = relZ+absZ-2
--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
In case you want to try out with workshop/reactions:
[BUILDING_WORKSHOP:DIG_SITE]
[NAME:Dig Site]
[NAME_COLOR:7:0:1]
[BUILD_LABOR:MINING]
[BUILD_KEY:CUSTOM_SHIFT_D]
[DIM:3:1]
[WORK_LOCATION:1:1]
[BLOCK:1:0:0:0]
[TILE:0:1:32:25:32]
[COLOR:0:1:0:0:0:7:0:0:0:0:0]
[TILE:1:1:32:25:32]
[COLOR:1:1:0:0:0:7:0:0:0:0:0]
[TILE:2:1:32:25:32]
[COLOR:2:1:0:0:0:7:0:0:0:0:0]
[TILE:3:1:25:157:152]
[COLOR:3:1:7:0:0:6:0:0:6:0:0]
[REACTION:DIG_HOVEL]
[NAME:Dig a warren (3x3)]
[BUILDING:DIG_SITE:CUSTOM_A]
[SKILL:MINING]
[PERMITTED_BUILDING:DIG_SITE]
[PERMITTED_REACTION:DIG_HOVEL]