Support default building inputs in dfhack.buildings.constructBuilding.

develop
Alexander Gavrilov 2012-05-06 19:11:29 +04:00
parent 9ad8d767b4
commit fca618ff1b
2 changed files with 368 additions and 5 deletions

@ -2,6 +2,336 @@ local dfhack = dfhack
local _ENV = dfhack.BASE_G local _ENV = dfhack.BASE_G
local buildings = dfhack.buildings local buildings = dfhack.buildings
local utils = require 'utils'
--[[ Building input material tables. ]]
local building_inputs = {
[df.building_type.Chair] = { { item_type=df.item_type.CHAIR, vector_id=df.job_item_vector_id.CHAIR } },
[df.building_type.Bed] = { { item_type=df.item_type.BED, vector_id=df.job_item_vector_id.BED } },
[df.building_type.Table] = { { item_type=df.item_type.TABLE, vector_id=df.job_item_vector_id.TABLE } },
[df.building_type.Coffin] = { { item_type=df.item_type.COFFIN, vector_id=df.job_item_vector_id.COFFIN } },
[df.building_type.FarmPlot] = { },
[df.building_type.Furnace] = { { flags2={ building_material=true, fire_safe=true, non_economic=true } } },
[df.building_type.TradeDepot] = { { flags2={ building_material=true, non_economic=true }, quantity=3 } },
[df.building_type.Door] = { { item_type=df.item_type.DOOR, vector_id=df.job_item_vector_id.DOOR } },
[df.building_type.Floodgate] = {
{
item_type=df.item_type.FLOODGATE,
vector_id=df.job_item_vector_id.FLOODGATE
}
},
[df.building_type.Box] = {
{
flags1={ empty=true },
item_type=df.item_type.BOX,
vector_id=df.job_item_vector_id.BOX
}
},
[df.building_type.Weaponrack] = {
{
item_type=df.item_type.WEAPONRACK,
vector_id=df.job_item_vector_id.WEAPONRACK
}
},
[df.building_type.Armorstand] = {
{
item_type=df.item_type.ARMORSTAND,
vector_id=df.job_item_vector_id.ARMORSTAND
}
},
[df.building_type.Workshop] = { { flags2={ building_material=true, non_economic=true } } },
[df.building_type.Cabinet] = {
{ item_type=df.item_type.CABINET, vector_id=df.job_item_vector_id.CABINET }
},
[df.building_type.Statue] = { { item_type=df.item_type.STATUE, vector_id=df.job_item_vector_id.STATUE } },
[df.building_type.WindowGlass] = { { item_type=df.item_type.WINDOW, vector_id=df.job_item_vector_id.WINDOW } },
[df.building_type.WindowGem] = {
{
item_type=df.item_type.SMALLGEM,
quantity=3,
vector_id=df.job_item_vector_id.ANY_GENERIC35
}
},
[df.building_type.Well] = {
{
item_type=df.item_type.BLOCKS,
vector_id=df.job_item_vector_id.ANY_GENERIC35
},
{
name='bucket',
flags2={ lye_milk_free=true },
item_type=df.item_type.BUCKET,
vector_id=df.job_item_vector_id.BUCKET
},
{
name='chain',
item_type=df.item_type.CHAIN,
vector_id=df.job_item_vector_id.CHAIN
},
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
},
[df.building_type.Bridge] = { { flags2={ building_material=true, non_economic=true }, quantity=-1 } },
[df.building_type.RoadDirt] = { },
[df.building_type.RoadPaved] = { { flags2={ building_material=true, non_economic=true }, quantity=-1 } },
[df.building_type.AnimalTrap] = {
{
flags1={ empty=true },
item_type=df.item_type.ANIMALTRAP,
vector_id=df.job_item_vector_id.ANIMALTRAP
}
},
[df.building_type.Support] = { { flags2={ building_material=true, non_economic=true } } },
[df.building_type.ArcheryTarget] = { { flags2={ building_material=true, non_economic=true } } },
[df.building_type.Chain] = { { item_type=df.item_type.CHAIN, vector_id=df.job_item_vector_id.CHAIN } },
[df.building_type.Cage] = { { item_type=df.item_type.CAGE, vector_id=df.job_item_vector_id.CAGE } },
[df.building_type.Weapon] = { { vector_id=df.job_item_vector_id.ANY_SPIKE } },
[df.building_type.ScrewPump] = {
{
item_type=df.item_type.BLOCKS,
vector_id=df.job_item_vector_id.ANY_GENERIC35
},
{
name='screw',
flags2={ screw=true },
item_type=df.item_type.TRAPCOMP,
vector_id=df.job_item_vector_id.ANY_WEAPON
},
{
name='pipe',
item_type=df.item_type.PIPE_SECTION,
vector_id=df.job_item_vector_id.PIPE_SECTION
}
},
[df.building_type.Construction] = { { flags2={ building_material=true, non_economic=true } } },
[df.building_type.Hatch] = {
{
item_type=df.item_type.HATCH_COVER,
vector_id=df.job_item_vector_id.HATCH_COVER
}
},
[df.building_type.GrateWall] = { { item_type=df.item_type.GRATE, vector_id=df.job_item_vector_id.GRATE } },
[df.building_type.GrateFloor] = { { item_type=df.item_type.GRATE, vector_id=df.job_item_vector_id.GRATE } },
[df.building_type.BarsVertical] = {
{ item_type=df.item_type.BAR, vector_id=df.job_item_vector_id.ANY_GENERIC35 }
},
[df.building_type.BarsFloor] = {
{ item_type=df.item_type.BAR, vector_id=df.job_item_vector_id.ANY_GENERIC35 }
},
[df.building_type.GearAssembly] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
},
[df.building_type.AxleHorizontal] = {
{ item_type=df.item_type.WOOD, vector_id=df.job_item_vector_id.WOOD, quantity=-1 }
},
[df.building_type.AxleVertical] = { { item_type=df.item_type.WOOD, vector_id=df.job_item_vector_id.WOOD } },
[df.building_type.WaterWheel] = {
{
item_type=df.item_type.WOOD,
quantity=3,
vector_id=df.job_item_vector_id.WOOD
}
},
[df.building_type.Windmill] = {
{
item_type=df.item_type.WOOD,
quantity=4,
vector_id=df.job_item_vector_id.WOOD
}
},
[df.building_type.TractionBench] = {
{
item_type=df.item_type.TRACTION_BENCH,
vector_id=df.job_item_vector_id.TRACTION_BENCH
}
},
[df.building_type.Slab] = { { item_type=df.item_type.SLAB } },
[df.building_type.NestBox] = { { has_tool_use=df.tool_uses.NEST_BOX, item_type=df.item_type.TOOL } },
[df.building_type.Hive] = { { has_tool_use=df.tool_uses.HIVE, item_type=df.item_type.TOOL } }
}
local furnace_inputs = {
[df.furnace_type.WoodFurnace] = { { flags2={ building_material=true, fire_safe=true, non_economic=true } } },
[df.furnace_type.Smelter] = { { flags2={ building_material=true, fire_safe=true, non_economic=true } } },
[df.furnace_type.GlassFurnace] = { { flags2={ building_material=true, fire_safe=true, non_economic=true } } },
[df.furnace_type.Kiln] = { { flags2={ building_material=true, fire_safe=true, non_economic=true } } },
[df.furnace_type.MagmaSmelter] = { { flags2={ building_material=true, magma_safe=true, non_economic=true } } },
[df.furnace_type.MagmaGlassFurnace] = { { flags2={ building_material=true, magma_safe=true, non_economic=true } } },
[df.furnace_type.MagmaKiln] = { { flags2={ building_material=true, magma_safe=true, non_economic=true } } }
}
local workshop_inputs = {
[df.workshop_type.Carpenters] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Farmers] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Masons] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Craftsdwarfs] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Jewelers] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.MetalsmithsForge] = {
{
name='anvil',
flags2={ fire_safe=true },
item_type=df.item_type.ANVIL,
vector_id=df.job_item_vector_id.ANVIL
},
{ flags2={ building_material=true, fire_safe=true, non_economic=true } }
},
[df.workshop_type.MagmaForge] = {
{
name='anvil',
flags2={ magma_safe=true },
item_type=df.item_type.ANVIL,
vector_id=df.job_item_vector_id.ANVIL
},
{ flags2={ building_material=true, magma_safe=true, non_economic=true } }
},
[df.workshop_type.Bowyers] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Mechanics] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Siege] = { { flags2={ building_material=true, non_economic=true }, quantity=3 } },
[df.workshop_type.Butchers] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Leatherworks] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Tanners] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Clothiers] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Fishery] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Still] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Loom] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Quern] = { { item_type=df.item_type.QUERN, vector_id=df.job_item_vector_id.QUERN } },
[df.workshop_type.Kennels] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Kitchen] = { { flags2={ building_material=true, non_economic=true } } },
[df.workshop_type.Ashery] = {
{
item_type=df.item_type.BLOCKS,
vector_id=df.job_item_vector_id.ANY_GENERIC35
},
{
name='barrel',
flags1={ empty=true },
item_type=df.item_type.BARREL,
vector_id=df.job_item_vector_id.BARREL
},
{
name='bucket',
flags2={ lye_milk_free=true },
item_type=df.item_type.BUCKET,
vector_id=df.job_item_vector_id.BUCKET
}
},
[df.workshop_type.Dyers] = {
{
name='barrel',
flags1={ empty=true },
item_type=df.item_type.BARREL,
vector_id=df.job_item_vector_id.BARREL
},
{
name='bucket',
flags2={ lye_milk_free=true },
item_type=df.item_type.BUCKET,
vector_id=df.job_item_vector_id.BUCKET
}
},
[df.workshop_type.Millstone] = {
{
item_type=df.item_type.MILLSTONE,
vector_id=df.job_item_vector_id.MILLSTONE
},
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
}
}
local trap_inputs = {
[df.trap_type.StoneFallTrap] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
},
[df.trap_type.WeaponTrap] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
},
{ vector_id=df.job_item_vector_id.ANY_WEAPON }
},
[df.trap_type.Lever] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
},
[df.trap_type.PressurePlate] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
},
[df.trap_type.CageTrap] = {
{
name='mechanism',
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
}
}
}
local function get_inputs_by_type(type,subtype,custom)
if type == df.building_type.Workshop then
return workshop_inputs[subtype]
elseif type == df.building_type.Furnace then
return furnace_inputs[subtype]
elseif type == df.building_type.Trap then
return trap_inputs[subtype]
else
return building_inputs[type]
end
end
local function augment_input(input, argtable)
local rv = {}
local arg = argtable[input.name or 'material']
if arg then
utils.assign(rv, arg)
end
utils.assign(rv, input)
if rv.mat_index and safe_index(rv, 'flags2', 'non_economic') then
rv.flags2.non_economic = false
end
rv.new = true
rv.name = nil
return rv
end
function buildings.getFiltersByType(argtable,type,subtype,custom)
local inputs = get_inputs_by_type(type,subtype,custom)
if not inputs then
return nil
end
local rv = {}
for i,v in ipairs(inputs) do
rv[i] = augment_input(v, argtable)
end
return rv
end
--[[ --[[
Wraps all steps necessary to create a building with Wraps all steps necessary to create a building with
a construct job into one function. a construct job into one function.
@ -30,6 +360,10 @@ local buildings = dfhack.buildings
filter = { { ... }, { ... }... } filter = { { ... }, { ... }... }
-- OR -- OR
abstract = true abstract = true
-- OR
material = { filter_properties... }
mechanism = { filter_properties... }
barrel, bucket, chain, anvil, screw, pipe
} }
Returns: the created building, or 'nil, error' Returns: the created building, or 'nil, error'
@ -39,14 +373,18 @@ function buildings.constructBuilding(info)
local btype = info.type local btype = info.type
local subtype = info.subtype or -1 local subtype = info.subtype or -1
local custom = info.custom or -1 local custom = info.custom or -1
local filters = info.filters
if not (info.pos or info.x) then if not (info.pos or info.x) then
error('position is required') error('position is required')
end end
if not (info.abstract or info.items or info.filters) then if not (info.abstract or info.items or filters) then
error('one of items, filters or abstract are required') filters = buildings.getFiltersByType(info,btype,subtype,custom)
elseif info.filters then if not filters then
for _,v in ipairs(info.filters) do error('one of items, filters or abstract is required')
end
elseif filters then
for _,v in ipairs(filters) do
v.new = true v.new = true
end end
end end
@ -84,7 +422,7 @@ function buildings.constructBuilding(info)
elseif info.items then elseif info.items then
ok = buildings.constructWithItems(instance, info.items) ok = buildings.constructWithItems(instance, info.items)
else else
ok = buildings.constructWithFilters(instance, info.filters) ok = buildings.constructWithFilters(instance, filters)
end end
if not ok then if not ok then
return nil, "could not construct the building" return nil, "could not construct the building"

@ -111,4 +111,29 @@ function make_sort_order(data,ordering)
return index return index
end end
--[[
Recursively assign data into a table.
--]]
function assign(tgt,src)
if df.isvalid(tgt) == 'ref' then
df.assign(tgt, src)
elseif type(tgt) == 'table' then
for k,v in pairs(src) do
if type(v) == 'table' or df.isvalid(v) == 'ref' then
local cv = tgt[k]
if cv == nil then
cv = {}
tgt[k] = cv
end
assign(cv, v)
else
tgt[k] = v
end
end
else
error('Invalid assign target type: '..tostring(tgt))
end
return tgt
end
return _ENV return _ENV