forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 4
/
combine-drinks.lua
122 lines (99 loc) · 4.19 KB
/
combine-drinks.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
-- Merge drink stacks in the selected stockpile
--[====[
combine-drinks
==============
Merge stacks of drinks in the selected stockpile.
]====]
local utils = require 'utils'
local validArgs = utils.invert({ 'max', 'stockpile' })
local args = utils.processArgs({...}, validArgs)
local max = 30
if args.max then max = tonumber(args.max) end
local stockpile = nil
if args.stockpile then stockpile = df.building.find(tonumber(args.stockpile)) end
local function itemsCompatible(item0, item1)
return item0:getType() == item1:getType()
and item0.mat_type == item1.mat_type
and item0.mat_index == item1.mat_index
end
local function getDrinks(items, drinks, index)
for i,d in ipairs(items) do
local foundDrink = nil
-- Skip items currently tasked
if #d.specific_refs == 0 then
if d:getType() == df.item_type.DRINK then
foundDrink = d
else
--print(d.id)
local containedItems = dfhack.items.getContainedItems(d)
-- Drink containers only contain one item
if #containedItems == 1 then
local possibleDrink = containedItems[1]
if #possibleDrink.specific_refs == 0 and possibleDrink:getType() == df.item_type.DRINK then
foundDrink = possibleDrink
end
end
end
end
if foundDrink ~= nil then
drinks[index] = foundDrink
index = index + 1
end
end
return index
end
local building = stockpile or dfhack.gui.getSelectedBuilding(true)
if building ~= nil and building:getType() ~= 29 then building = nil end
if building == nil then
qerror("Select a stockpile")
else
local rootItems = dfhack.buildings.getStockpileContents(building)
if #rootItems == 0 then
qerror("Select a non-empty stockpile")
else
local drinks = { } --as:df.item_drinkst[]
local drinkCount = getDrinks(rootItems, drinks, 0)
--for i,p in ipairs(drinks) do
-- print(i .. ': ' .. dfhack.items.getDescription(p, p:getType()))
--end
local removedDrinks = {} --as:bool[]
for i=0,(drinkCount-2) do
local currentDrink = drinks[i]
local itemsNeeded = max - currentDrink.stack_size
--print('processing ' .. dfhack.items.getDescription(currentDrink, currentDrink:getType()) .. ' needs ' .. itemsNeeded)
if removedDrinks[currentDrink.id] == nil and itemsNeeded > 0 then
for j=(i+1),(drinkCount-1) do
local sourceDrink = drinks[j]
--print('\ttrying ' .. dfhack.items.getDescription(sourceDrink, sourceDrink:getType()))
if removedDrinks[sourceDrink.id] == nil and itemsCompatible(currentDrink, sourceDrink) then
local amountToMove = math.min(itemsNeeded, sourceDrink.stack_size)
--print('\tmoving ' .. amountToMove)
itemsNeeded = itemsNeeded - amountToMove
currentDrink.stack_size = currentDrink.stack_size + amountToMove
if sourceDrink.stack_size == amountToMove then
--print('\tadding remove id ' .. sourceDrink.id)
removedDrinks[sourceDrink.id] = true
else
sourceDrink.stack_size = sourceDrink.stack_size - amountToMove
end
end
end
end
end
local removedDrinkCount = 0
for id,removed in pairs(removedDrinks) do
if removed then
local removedDrink = df.item.find(id)
removedDrinkCount = removedDrinkCount + 1
--print('remove id=' .. id .. ' drink=' .. dfhack.items.getDescription(removedDrink, removedDrink:getType()))
dfhack.items.remove(removedDrink)
end
end
print('found ' .. drinkCount .. ' drinks')
print('removed ' .. removedDrinkCount .. ' drinks')
end
--elseif item:getType() == 68 then
--handleDrink(item)
--else
-- qerror("Select a drink or a drink.")
end