dfhack/scripts/modtools/outside-only.lua

135 lines
3.2 KiB
Lua

--scripts/modtools/outsideOnly.lua
--author expwnent
--enables outside only and inside only buildings
local eventful = require 'plugins.eventful'
local utils = require 'utils'
buildingType = buildingType or utils.invert({'EITHER','OUTSIDE_ONLY','INSIDE_ONLY'})
registeredBuildings = registeredBuildings or {}
checkEvery = checkEvery or 100
timeoutId = timeoutId or nil
eventful.enableEvent(eventful.eventType.UNLOAD,1)
eventful.onUnload.outsideOnly = function()
registeredBuildings = {}
checkEvery = 100
timeoutId = nil
end
local function destroy(building)
if #building.jobs > 0 and building.jobs[0] and building.jobs[0].job_type == df.job_type.DestroyBuilding then
return
end
local b = dfhack.buildings.deconstruct(building)
if b then
--TODO: print an error message to the user so they know
return
end
-- building.flags.almost_deleted = 1
end
local function checkBuildings()
local toDestroy = {}
local function forEach(building)
if building:getCustomType() < 0 then
--TODO: support builtin building types if someone wants
return
end
local pos = df.coord:new()
pos.x = building.centerx
pos.y = building.centery
pos.z = building.z
local outside = dfhack.maps.getTileBlock(pos).designation[pos.x%16][pos.y%16].outside
local def = df.global.world.raws.buildings.all[building:getCustomType()]
local btype = registeredBuildings[def.code]
if btype then
-- print('outside: ' .. outside==true .. ', type: ' .. btype)
end
if not btype or btype == buildingType.EITHER then
registeredBuildings[def.code] = nil
return
elseif btype == buildingType.OUTSIDE_ONLY then
if outside then
return
end
else
if not outside then
return
end
end
table.insert(toDestroy,building)
end
for _,building in ipairs(df.global.world.buildings.all) do
forEach(building)
end
for _,building in ipairs(toDestroy) do
destroy(building)
end
if timeoutId then
dfhack.timeout_active(timeoutId,nil)
timeoutId = nil
end
timeoutId = dfhack.timeout(checkEvery, 'ticks', checkBuildings)
end
eventful.enableEvent(eventful.eventType.BUILDING, 100)
eventful.onBuildingCreatedDestroyed.outsideOnly = function(buildingId)
checkBuildings()
end
validArgs = validArgs or utils.invert({
'help',
'clear',
'checkEvery',
'building',
'type'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/modtools/outside-only
arguments
-help
print this help message
-clear
clears the list of registered buildings
-checkEvery n
set how often existing buildings are checked for whether they are in the appropriate location to n ticks
-type [EITHER, OUTSIDE_ONLY, INSIDE_ONLY]
specify what sort of restriction to put on the building
-building name
specify the id of the building
]])
return
end
if args.clear then
registeredBuildings = {}
end
if args.checkEvery then
if not tonumber(args.checkEvery) then
error('Invalid checkEvery.')
end
checkEvery = tonumber(args.checkEvery)
end
if not args.building then
return
end
if not args['type'] then
print 'outside-only: please specify type'
return
end
if not buildingType[args['type']] then
error('Invalid building type: ' .. args['type'])
end
registeredBuildings[args.building] = buildingType[args['type']]
checkBuildings()