forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 1
/
add-recipe.lua
201 lines (174 loc) · 6.74 KB
/
add-recipe.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
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
-- Script to add unknown crafting recipes to the player's civ.
--[====[
add-recipe
==========
Adds unknown weapon and armor crafting recipes to your civ.
E.g. some civilizations never learn to craft high boots. This script can
help with that, and more. Only weapons, armor, and tools are currently supported;
things such as instruments are not. Available options:
* ``add-recipe all`` adds *all* available weapons and armor, including exotic items
like blowguns, two-handed swords, and capes.
* ``add-recipe native`` adds only native (but unknown) crafting recipes. Civilizations
pick randomly from a pool of possible recipes, which means not all civs get
high boots, for instance. This command gives you all the recipes your
civilisation could have gotten.
* ``add-recipe single <item token>`` adds a single item by the given
item token. For example::
add-recipe single SHOES:ITEM_SHOES_BOOTS
]====]
local itemDefs = df.global.world.raws.itemdefs
local resources = df.historical_entity.find(df.global.ui.civ_id).resources
local civ = df.historical_entity.find(df.global.ui.civ_id).entity_raw
if (resources == nil) then
qerror("Could not find entity resources")
elseif (itemDefs == nil) then
qerror("Could not find item raws!")
elseif (civ == nil) then
qerror("Could not find civilization type!")
end
--array that categorises the various containers we need to access per type
--each type is represented by an array with the following elements:
--1: the currently known recipes to the player civ
--2: the native (non-exotic) recipes to the player civ
--3: all possible recipes including exotic
local categories = { --as:{1:'number[]',2:'number[]',3:'df.itemdef[]'}[]
weapon = {resources.weapon_type, civ.equipment.weapon_id, itemDefs.weapons },
shield = {resources.shield_type, civ.equipment.shield_id, itemDefs.shields },
ammo = {resources.ammo_type, civ.equipment.ammo_id, itemDefs.ammo },
armor = {resources.armor_type, civ.equipment.armor_id, itemDefs.armor },
gloves = {resources.gloves_type, civ.equipment.gloves_id, itemDefs.gloves },
shoes = {resources.shoes_type, civ.equipment.shoes_id, itemDefs.shoes },
helm = {resources.helm_type, civ.equipment.helm_id, itemDefs.helms },
pants = {resources.pants_type, civ.equipment.pants_id, itemDefs.pants },
tool = {resources.tool_type, civ.equipment.tool_id, itemDefs.tools}
}
local diggers = resources.digger_type
function checkKnown(known, itemType)
--checks if the item with the given subtype is already known to the civ
--params:
--known: the resources field for the civ
--itemType: the item subtype we're checking
for _, id in ipairs(known) do
if id == itemType then
return true
end
end
return false
end
function checkNative(native, itemType)
--checks if the given itemtype is native to the player's civ
--params:
--native: the list of native item types
--itemType: the item subtype we're checking
for _, id in ipairs(native) do
if id == itemType then
return true
end
end
return false
end
function addItems(category, exotic)
--makes all available recipes of the given category known to the player's civ
--params:
--category: the category of items we're adding
--exotic: whether to add exotic items
--returns: list of item objects that were added
local known = category[1]
local native = category[2]
local all = category[3]
local added = {} --as:df.itemdef[]
for _, item in ipairs(all) do
local item = item --as:df.itemdef_weaponst
local subtype = item.subtype
local itemOk = false
--check if it's a training weapon
local t1, t2 = pcall(function () return item.flags.TRAINING == false end)
local training = not(not t1 or t2)
--we don't want procedural items with adjectives such as "wavy spears"
--(because they don't seem to be craftable even if added)
--nor do we want known items or training items (because adding training
--items seems to allow them to be made out of metals)
if (item.adjective == "" and not training and not checkKnown(known, subtype)) then
itemOk = true
end
if (not exotic and not checkNative(native, subtype)) then
itemOk = false
end
--check that the weapon we're adding is not already known to the civ as
--a digging implement so picks don't get duplicated
if (checkKnown(diggers, subtype)) then
itemOk = false
end
if (itemOk) then
known:insert('#', subtype)
table.insert(added, item)
end
end
return added
end
function printItems(itemList)
for _, v in ipairs(itemList) do
local v = v --as:df.itemdef_weaponst
print("Added recipe " .. v.id .. " (" .. v.name .. ")")
end
end
function addAllItems(exotic)
printItems(addItems(categories.weapon, exotic))
printItems(addItems(categories.shield, exotic))
printItems(addItems(categories.ammo, exotic))
printItems(addItems(categories.armor, exotic))
printItems(addItems(categories.gloves, exotic))
printItems(addItems(categories.shoes, exotic))
printItems(addItems(categories.helm, exotic))
printItems(addItems(categories.pants, exotic))
printItems(addItems(categories.tool, exotic))
end
function addSingleItem(itemstring)
local itemType = nil --The category of the item, the word before the ":"
local itemId = nil --The item within that category, what goes after the ":"
if (itemstring ~= nil) then
itemType, itemId = string.match(itemstring, "(.*):(.*)")
else
print("Usage: add-recipe single <item name> | Example: add-recipe single SHOES:ITEM_SHOES_BOOTS")
return
end
if (itemType == nil or itemId == nil) then
print("Usage: add-recipe single <item name> | Example: add-recipe single SHOES:ITEM_SHOES_BOOTS")
return
end
local category = categories[string.lower(itemType)]
if (category == nil) then return end
local known = category[1]
local all = category[3]
local addedItem = nil
--assume the user knows what they're doing, so no need for sanity checks
for _, item in ipairs(all) do
if (item.id == itemId) then
known:insert('#', item.subtype)
addedItem = item
break
end
end
if (addedItem ~= nil) then
local addedItem = addedItem --as:df.itemdef_weaponst
print("Added recipe " .. addedItem.id .. " (" .. addedItem.name .. ")")
else
print("Could not add recipe: invalid item name")
end
end
local args = {...}
local cmd = args[1]
if (cmd == "all") then
addAllItems(true)
elseif (cmd == "native") then
addAllItems(false)
elseif (cmd == "single") then
addSingleItem(args[2])
else
print("Available options:\n"
.."all: adds all supported crafting recipes.\n"
.."native: adds only unknown native recipes (eg. high boots for "
.."some dwarves)\n"
.."single: adds a specific item by itemstring (eg. "
.."SHOES:ITEM_SHOES_BOOTS)")
end