forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathautofish.lua
More file actions
208 lines (171 loc) · 5.93 KB
/
autofish.lua
File metadata and controls
208 lines (171 loc) · 5.93 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
-- handles automatic fishing jobs to limit the number of fish the fortress keeps on hand
-- autofish [enable | disable] <max> [min] [--include-raw | -r]
--@ enable=true
--@ module=true
local json = require("json")
local persist = require("persist-table")
local argparse = require("argparse")
local repeatutil = require("repeat-util")
local GLOBAL_KEY = "autofish"
-- set default enabled state
enabled = enabled or false
set_maxFish = set_maxFish or 100
set_minFish = set_minFish or 50
set_useRaw = set_useRaw or true
isFishing = isFishing or true
local timer = nil
function isEnabled()
return enabled
end
local function persist_state()
persist.GlobalTable[GLOBAL_KEY] = json.encode({enabled=enabled,
set_maxFish=set_maxFish, set_minFish=set_minFish, set_useRaw=set_useRaw,
isFishing=isFishing
})
end
local function load_state()
-- load persistent data
local persisted_data = json.decode(persist.GlobalTable[GLOBAL_KEY] or "")
enabled = (persisted_data or {enabled=false})["enabled"]
set_maxFish = (persisted_data or {set_maxFish=100})["set_maxFish"]
set_minFish = (persisted_data or {set_minFish=50})["set_minFish"]
set_useRaw = (persisted_data or {set_useRaw=true})["set_useRaw"]
isFishing = (persisted_data or {isFishing=true})["isFishing"]
end
-- toggle the fishing labour on all dwarves/work detail if enabled
function toggle_fishing_labour(state)
-- pass true to state to turn on, otherwise disable
-- find all work details that have fishing enabled:
local work_details = df.global.plotinfo.hauling.work_details
for _,v in pairs(work_details) do
if v.allowed_labors.FISH then
-- set limited to true just in case a custom work detail is being
-- changed, to prevent *all* dwarves from fishing.
v.work_detail_flags.limited = true
v.work_detail_flags.enabled = state
-- workaround to actually enable labours
for _,v2 in ipairs(v.assigned_units) do
-- find unit by ID and toggle fishing
local unit = df.unit.find(v2)
unit.status.labors.FISH = state
end
end
end
isFishing = state -- save current state
-- let the user know we've got enough, or run out of fish
if isFishing then
print("autofish: Re-enabling fishing, fallen below minimum.")
else
print("autofish: Disabling fishing, reached desired quota.")
end
end
-- check if an item isn't forbidden/rotten/on fire/etc..
function isValidItem(item)
local flags = item.flags
if flags.rotten or flags.trader or flags.hostile or flags.forbid
or flags.dump or flags.on_fire or flags.garbage_collect or flags.owned
or flags.removed or flags.encased or flags.spider_web then
return false
end
return true
end
function event_loop()
if not enabled then return end
local world = df.global.world
-- count the number of valid fish we have. (not rotten, forbidden, on fire, dumping...)
local prepared, raw = 0, 0
for k,v in pairs(world.items.other[df.items_other_id.IN_PLAY]) do
if v:getType() == df.item_type.FISH and isValidItem(v) then
prepared = prepared + v:getStackSize()
end
if (v:getType() == df.item_type.FISH_RAW and isValidItem(v)) and set_useRaw then
raw = raw + v:getStackSize()
end
end
-- hande pausing/resuming labour
local numFish = set_useRaw and (prepared+raw) or prepared
if isFishing and (numFish >= set_maxFish) then
toggle_fishing_labour(false)
elseif not isFishing and (numFish < set_minFish) then
toggle_fishing_labour(true)
end
persist_state()
-- check weekly
repeatutil.scheduleUnlessAlreadyScheduled(GLOBAL_KEY, 7, "days", event_loop)
end
local function print_status()
print(string.format("autofish is currently %s.\n", (enabled and "enabled" or "disabled")))
if enabled then
local rfs
rfs = set_useRaw and "raw & prepared" or "prepared"
print(string.format("Stopping at %s %s fish.", set_maxFish, rfs))
print(string.format("Restarting at %s %s fish.", set_minFish, rfs))
if isFishing then
print("\nCurrently allowing fishing.")
else
print("\nCurrently not allowing fishing.")
end
end
end
-- handle loading
dfhack.onStateChange[GLOBAL_KEY] = function(sc)
-- unload with game
if sc == SC_MAP_UNLOADED then
enabled = false
return
end
if sc ~= SC_MAP_LOADED or df.global.gamemode ~= df.game_mode.DWARF then
return
end
load_state()
-- run the main code
event_loop()
end
-- sanity checks?
if dfhack_flags.module then
return
end
if df.global.gamemode ~= df.game_mode.DWARF or not dfhack.isMapLoaded() then
dfhack.printerr("autofish needs a loaded fortress to work")
return
end
-- argument handling
local args = {...}
if dfhack_flags and dfhack_flags.enable then
args = {dfhack_flags.enable_state and "enable" or "disable"}
end
-- find flags in args:
local positionals = argparse.processArgsGetopt(args,
{{"r", "toggle-raw",
handler=function() set_useRaw = not set_useRaw end}
})
load_state()
if positionals[1] == "enable" then
enabled = true
elseif positionals[1] == "disable" then
enabled = false
persist_state()
repeatutil.cancel(GLOBAL_KEY)
return
elseif positionals[1] == "status" then
print_status()
return
elseif positionals ~= nil then
-- positionals is a number?
if positionals[1] and tonumber(positionals[1]) then
-- assume we're changing setting:
set_maxFish = tonumber(positionals[1])
else
-- invalid or no argument
return
end
if positionals[2] and tonumber(positionals[2]) then
set_minFish = tonumber(positionals[2])
end
-- a setting probably changed, save & show the updated settings.
persist_state()
print_status()
return
end
event_loop()
persist_state()