forked from DFHack/dfhack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoutside-only.lua
142 lines (125 loc) · 3.49 KB
/
outside-only.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--scripts/modtools/outsideOnly.lua
--author expwnent
--enables outside only and inside only buildings
--[[=begin
modtools/outside-only
=====================
This allows you to specify certain custom buildings as outside only, or inside
only. If the player attempts to build a building in an inappropriate location,
the building will be destroyed.
=end]]
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()