526 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Lua
		
	
			
		
		
	
	
			526 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Lua
		
	
| local dfhack = dfhack
 | |
| local _ENV = dfhack.BASE_G
 | |
| local buildings = dfhack.buildings
 | |
| 
 | |
| local utils = require 'utils'
 | |
| 
 | |
| -- 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 } },
 | |
|     [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.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.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.SMALLGEM
 | |
|         }
 | |
|     },
 | |
|     [df.building_type.Well] = {
 | |
|         {
 | |
|             item_type=df.item_type.BLOCKS,
 | |
|             vector_id=df.job_item_vector_id.BLOCKS
 | |
|         },
 | |
|         {
 | |
|             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] = { { name='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.BLOCKS
 | |
|         },
 | |
|         {
 | |
|             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.BAR }
 | |
|     },
 | |
|     [df.building_type.BarsFloor] = {
 | |
|         { item_type=df.item_type.BAR, vector_id=df.job_item_vector_id.BAR }
 | |
|     },
 | |
|     [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 } },
 | |
|     [df.building_type.OfferingPlace] = { { has_tool_use=df.tool_uses.PLACE_OFFERING, item_type=df.item_type.TOOL } },
 | |
|     [df.building_type.Bookcase] = { { has_tool_use=df.tool_uses.BOOKCASE, item_type=df.item_type.TOOL } },
 | |
|     [df.building_type.DisplayFurniture] = { { has_tool_use=df.tool_uses.DISPLAY_OBJECT, item_type=df.item_type.TOOL } },
 | |
|     [df.building_type.Rollers] = {
 | |
|         {
 | |
|             name='mechanism',
 | |
|             item_type=df.item_type.TRAPPARTS,
 | |
|             quantity=-1,
 | |
|             vector_id=df.job_item_vector_id.TRAPPARTS
 | |
|         },
 | |
|         {
 | |
|             name='chain',
 | |
|             item_type=df.item_type.CHAIN,
 | |
|             vector_id=df.job_item_vector_id.CHAIN
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| --[[ 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 } } },
 | |
|     [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 } } }
 | |
| }
 | |
| 
 | |
| --[[ 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 } } },
 | |
|     [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.BLOCKS
 | |
|         },
 | |
|         {
 | |
|             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
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| --[[ Trap building input material table. ]]
 | |
| 
 | |
| 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
 | |
|         },
 | |
|         {
 | |
|             name='weapon',
 | |
|             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
 | |
|         }
 | |
|     },
 | |
|     [df.trap_type.TrackStop] = { { flags2={ building_material=true, non_economic=true } } }
 | |
| }
 | |
| local siegeengine_input = {
 | |
|     [df.siegeengine_type.Catapult] = {
 | |
|         {
 | |
|             item_type=df.item_type.CATAPULTPARTS,
 | |
|             vector_id=df.job_item_vector_id.CATAPULTPARTS,
 | |
|             quantity=3
 | |
|         }
 | |
|     },
 | |
|     [df.siegeengine_type.Ballista] = {
 | |
|         {
 | |
|             item_type=df.item_type.BALLISTAPARTS,
 | |
|             vector_id=df.job_item_vector_id.BALLISTAPARTS,
 | |
|             quantity=3
 | |
|         }
 | |
|     },
 | |
| }
 | |
| --[[ 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
 | |
|         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
 | |
|         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]
 | |
|     elseif type == df.building_type.SiegeEngine then
 | |
|         return siegeengine_input[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
 | |
|     a construct job into one function.
 | |
| 
 | |
|     dfhack.buildings.constructBuilding{
 | |
|       -- Position:
 | |
|         pos = { x = ..., y = ..., z = ... },
 | |
|       -- OR
 | |
|         x = ..., y = ..., z = ...,
 | |
| 
 | |
|       -- Type:
 | |
|         type = df.building_type.FOO, subtype = ..., custom = ...,
 | |
| 
 | |
|       -- Field initialization:
 | |
|         fields = { ... },
 | |
| 
 | |
|       -- Size and orientation:
 | |
|         width = ..., height = ..., direction = ...,
 | |
| 
 | |
|       -- Abort if not all tiles in the rectangle are available:
 | |
|         full_rectangle = true,
 | |
| 
 | |
|       -- Materials:
 | |
|         items = { item, item ... },
 | |
|       -- OR
 | |
|         filters = { { ... }, { ... }... }
 | |
|       -- OR
 | |
|         abstract = true
 | |
|       -- OR
 | |
|         material = { filter_properties... }
 | |
|         mechanism = { filter_properties... }
 | |
|         barrel, bucket, chain, anvil, screw, pipe
 | |
|     }
 | |
| 
 | |
|     Returns: the created building, or 'nil, error'
 | |
| --]]
 | |
| 
 | |
| function buildings.constructBuilding(info)
 | |
|     local btype = info.type
 | |
|     local subtype = info.subtype or -1
 | |
|     local custom = info.custom or -1
 | |
|     local filters = info.filters
 | |
| 
 | |
|     if not (info.pos or info.x) then
 | |
|         error('position is required')
 | |
|     end
 | |
|     if not (info.abstract or info.items or filters) then
 | |
|         filters = buildings.getFiltersByType(info,btype,subtype,custom)
 | |
|         if not filters then
 | |
|             error('one of items, filters or abstract is required')
 | |
|         end
 | |
|     elseif filters then
 | |
|         for _,v in ipairs(filters) do
 | |
|             v.new = true
 | |
|         end
 | |
|     end
 | |
|     if type(btype) ~= 'number' or not df.building_type[btype] then
 | |
|         error('Invalid building type: '..tostring(btype))
 | |
|     end
 | |
| 
 | |
|     local pos = info.pos or xyz2pos(info.x, info.y, info.z)
 | |
| 
 | |
|     local instance = buildings.allocInstance(pos, btype, subtype, custom)
 | |
|     if not instance then
 | |
|         error('Could not create building of type '..df.building_type[btype])
 | |
|     end
 | |
| 
 | |
|     local to_delete = instance
 | |
|     return dfhack.with_finalize(
 | |
|         function()
 | |
|             -- ensure we don't leak extents created by Buildings::checkFreeTiles
 | |
|             if to_delete and to_delete.room.extents then
 | |
|                 df.delete(to_delete.room.extents)
 | |
|                 to_delete.room.extents = nil
 | |
|             end
 | |
|             df.delete(to_delete)
 | |
|         end,
 | |
|         function()
 | |
|             if info.fields then
 | |
|                 instance:assign(info.fields)
 | |
|             end
 | |
|             local ok,w,h,area,r_area = buildings.setSize(
 | |
|                 instance,info.width,info.height,info.direction
 | |
|             )
 | |
|             if not ok then
 | |
|                 return nil, "cannot place at this position"
 | |
|             end
 | |
|             if info.full_rectangle and area ~= r_area then
 | |
|                 return nil, "not all tiles can be used"
 | |
|             end
 | |
|             if info.abstract then
 | |
|                 ok = buildings.constructAbstract(instance)
 | |
|             elseif info.items then
 | |
|                 ok = buildings.constructWithItems(instance, info.items)
 | |
|             else
 | |
|                 ok = buildings.constructWithFilters(instance, filters)
 | |
|             end
 | |
|             if not ok then
 | |
|                 return nil, "could not construct the building"
 | |
|             end
 | |
|             -- Success
 | |
|             to_delete = nil
 | |
|             return instance
 | |
|         end
 | |
|     )
 | |
| end
 | |
| 
 | |
| return buildings
 |