135 lines
3.2 KiB
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()
|
|
|