summaryrefslogtreecommitdiff
path: root/library/lua
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-05-13 18:39:00 +0400
committerAlexander Gavrilov2012-05-13 18:39:00 +0400
commit642a625586b9d40440bd3ce05d827f707ccce5ac (patch)
tree018a49a4309251d2a9352149bbcbeb6675dbaad6 /library/lua
parent87ec1de891625e9dc68924c570ede0fe23b4b6b7 (diff)
downloaddfhack-642a625586b9d40440bd3ce05d827f707ccce5ac.tar.gz
dfhack-642a625586b9d40440bd3ce05d827f707ccce5ac.tar.bz2
dfhack-642a625586b9d40440bd3ce05d827f707ccce5ac.tar.xz
Support custom buildings in dfhack.buildings.getFiltersByType.
Also document it and constructBuilding in Lua API docs.
Diffstat (limited to 'library/lua')
-rw-r--r--library/lua/dfhack/buildings.lua65
-rw-r--r--library/lua/utils.lua62
2 files changed, 119 insertions, 8 deletions
diff --git a/library/lua/dfhack/buildings.lua b/library/lua/dfhack/buildings.lua
index eb0a6a5b..ad82da89 100644
--- a/library/lua/dfhack/buildings.lua
+++ b/library/lua/dfhack/buildings.lua
@@ -4,7 +4,32 @@ local buildings = dfhack.buildings
local utils = require 'utils'
---[[ Building input material tables. ]]
+-- Uninteresting values for filter attributes when reading them from DF memory.
+-- Differs from the actual defaults of the job_item constructor in allow_artifact.
+
+buildings.input_filter_defaults = {
+ item_type = -1,
+ item_subtype = -1,
+ mat_type = -1,
+ mat_index = -1,
+ flags1 = {},
+ -- Instead of noting those that allow artifacts, mark those that forbid them.
+ -- Leaves actually enabling artifacts to the discretion of the API user,
+ -- which is the right thing because unlike the game UI these filters are
+ -- used in a way that does not give the user a chance to choose manually.
+ flags2 = { allow_artifact = true },
+ flags3 = {},
+ flags4 = 0,
+ flags5 = 0,
+ reaction_class = '',
+ has_material_reaction_product = '',
+ metal_ore = -1,
+ min_dimension = -1,
+ has_tool_use = -1,
+ quantity = 1
+}
+
+--[[ Building input material table. ]]
local building_inputs = {
[df.building_type.Chair] = { { item_type=df.item_type.CHAIR, vector_id=df.job_item_vector_id.CHAIR } },
@@ -12,7 +37,6 @@ local building_inputs = {
[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] = {
@@ -40,7 +64,6 @@ local building_inputs = {
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 }
},
@@ -89,7 +112,7 @@ local building_inputs = {
[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.Weapon] = { { name='weapon', vector_id=df.job_item_vector_id.ANY_SPIKE } },
[df.building_type.ScrewPump] = {
{
item_type=df.item_type.BLOCKS,
@@ -158,6 +181,8 @@ local building_inputs = {
[df.building_type.Hive] = { { has_tool_use=df.tool_uses.HIVE, item_type=df.item_type.TOOL } }
}
+--[[ Furnace building input material table. ]]
+
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 } } },
@@ -168,6 +193,8 @@ local furnace_inputs = {
[df.furnace_type.MagmaKiln] = { { flags2={ building_material=true, magma_safe=true, non_economic=true } } }
}
+--[[ Workshop building input material table. ]]
+
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 } } },
@@ -250,6 +277,8 @@ local workshop_inputs = {
}
}
+--[[ Trap building input material table. ]]
+
local trap_inputs = {
[df.trap_type.StoneFallTrap] = {
{
@@ -264,7 +293,10 @@ local trap_inputs = {
item_type=df.item_type.TRAPPARTS,
vector_id=df.job_item_vector_id.TRAPPARTS
},
- { vector_id=df.job_item_vector_id.ANY_WEAPON }
+ {
+ name='weapon',
+ vector_id=df.job_item_vector_id.ANY_WEAPON
+ }
},
[df.trap_type.Lever] = {
{
@@ -289,11 +321,28 @@ local trap_inputs = {
}
}
+--[[ Functions for lookup in tables. ]]
+
+local function get_custom_inputs(custom)
+ local defn = df.building_def.find(custom)
+ if defn ~= nil then
+ return utils.clone_with_default(defn.build_items, buildings.input_filter_defaults)
+ end
+end
+
local function get_inputs_by_type(type,subtype,custom)
if type == df.building_type.Workshop then
- return workshop_inputs[subtype]
+ if subtype == df.workshop_type.Custom then
+ return get_custom_inputs(custom)
+ else
+ return workshop_inputs[subtype]
+ end
elseif type == df.building_type.Furnace then
- return furnace_inputs[subtype]
+ if subtype == df.furnace_type.Custom then
+ return get_custom_inputs(custom)
+ else
+ return furnace_inputs[subtype]
+ end
elseif type == df.building_type.Trap then
return trap_inputs[subtype]
else
@@ -357,7 +406,7 @@ end
-- Materials:
items = { item, item ... },
-- OR
- filter = { { ... }, { ... }... }
+ filters = { { ... }, { ... }... }
-- OR
abstract = true
-- OR
diff --git a/library/lua/utils.lua b/library/lua/utils.lua
index 96ab2b19..e67801f4 100644
--- a/library/lua/utils.lua
+++ b/library/lua/utils.lua
@@ -221,6 +221,68 @@ function clone(obj,deep)
end
end
+local function get_default(default,key,base)
+ if type(default) == 'table' then
+ local dv = default[key]
+ if dv == nil then
+ dv = default._default
+ end
+ if dv == nil then
+ dv = base
+ end
+ return dv
+ else
+ return default
+ end
+end
+
+-- Copy the object as lua data structures, skipping values matching defaults.
+function clone_with_default(obj,default,force)
+ local rv = nil
+ local function setrv(k,v)
+ if v ~= nil then
+ if rv == nil then
+ rv = {}
+ end
+ rv[k] = v
+ end
+ end
+ if default == nil then
+ return nil
+ elseif type(obj) == 'table' then
+ for k,v in pairs(obj) do
+ setrv(k, clone_with_default(v, get_default(default,k)))
+ end
+ elseif df.isvalid(obj) == 'ref' then
+ local kind = obj._kind
+ if kind == 'primitive' then
+ return clone_with_default(obj.value,default,force)
+ elseif kind == 'bitfield' then
+ for k,v in pairs(obj) do
+ setrv(k, clone_with_default(v, get_default(default,k,false)))
+ end
+ elseif kind == 'container' then
+ for k,v in ipairs(obj) do
+ setrv(k+1, clone_with_default(v, default, true))
+ end
+ else -- struct
+ for k,v in pairs(obj) do
+ setrv(k, clone_with_default(v, get_default(default,k)))
+ end
+ end
+ elseif obj == default and not force then
+ return nil
+ elseif obj == nil then
+ return NULL
+ else
+ return obj
+ end
+ if force and rv == nil then
+ rv = {}
+ end
+ return rv
+end
+
-- Sort a vector or lua table
function sort_vector(vector,field,cmp)
local fcmp = compare_field(field,cmp)