]> git.lizzy.rs Git - Crafter.git/blob - mods/too_many_items/init.lua
55961888ca20e0bf7bcc2b96c386cee2240266d6
[Crafter.git] / mods / too_many_items / init.lua
1 local minetest,pairs = minetest,pairs
2
3 local tmi_master_inventory = {}
4 local pool = {}
5 local max = 7*7
6 --2x2 formspec
7 local base_inv = 
8 "size[17.2,8.75]"..
9 "background[-0.19,-0.25;9.41,9.49;main_inventory.png]"..
10 "listcolors[#8b8a89;#c9c3c6;#3e3d3e;#000000;#FFFFFF]"..
11 "list[current_player;main;0,4.5;9,1;]".. --hot bar
12 "list[current_player;main;0,6;9,3;9]".. --big part
13 "list[current_player;craft;2.5,1;2,2;]"..
14 --armor slots
15 "list[current_player;armor_head;0.25,0;1,1;]"..
16 "list[current_player;armor_torso;0.25,1;1,1;]"..
17 "list[current_player;armor_legs;0.25,2;1,1;]"..
18 "list[current_player;armor_feet;0.25,3;1,1;]"..
19 --craft preview with ring
20 "list[current_player;craftpreview;6.1,1.5;1,1;]"..
21 "listring[current_player;main]"..
22 "listring[current_player;craft]"
23 --this is the 3x3 crafting table formspec
24 local crafting_table_inv = 
25 "size[17.2,8.75]"..
26 "background[-0.19,-0.25;9.41,9.49;crafting_inventory_workbench.png]"..
27 "listcolors[#8b8a89;#c9c3c6;#3e3d3e;#000000;#FFFFFF]"..
28 "list[current_player;main;0,4.5;9,1;]".. --hot bar
29 "list[current_player;main;0,6;9,3;9]".. --big part
30 "list[current_player;craft;1.75,0.5;3,3;]"..
31 --armor slots
32 "list[current_player;armor_head;0.25,0;1,1;]"..
33 "list[current_player;armor_torso;0.25,1;1,1;]"..
34 "list[current_player;armor_legs;0.25,2;1,1;]"..
35 "list[current_player;armor_feet;0.25,3;1,1;]"..
36 --craft preview with ring
37 "list[current_player;craftpreview;6.1,1.5;1,1;]"..
38 "listring[current_player;main]"..
39 "listring[current_player;craft]"
40 --this is from Linuxdirk, thank you AspireMint for showing me this
41 local recipe_converter = function (items, width)
42     local usable_recipe = { {}, {}, {} }
43
44     -- The recipe is a shapeless recipe so all items are in one table
45     if width == 0 then
46         usable_recipe = items
47     end
48
49     -- x _ _
50     -- x _ _
51     -- x _ _
52     if width == 1 then
53         usable_recipe[1][1] = items[1] or ''
54         usable_recipe[2][1] = items[2] or ''
55         usable_recipe[3][1] = items[3] or ''
56     end
57
58     -- x x _
59     -- x x _
60     -- x x _
61     if width == 2 then
62         usable_recipe[1][1] = items[1] or ''
63         usable_recipe[1][2] = items[2] or ''
64         usable_recipe[2][1] = items[3] or ''
65         usable_recipe[2][2] = items[4] or ''
66         usable_recipe[3][1] = items[5] or ''
67         usable_recipe[3][2] = items[6] or ''
68     end
69
70     -- x x x
71     -- x x x
72     -- x x x
73     if width == 3 then
74         usable_recipe[1][1] = items[1] or ''
75         usable_recipe[1][2] = items[2] or ''
76         usable_recipe[1][3] = items[3] or ''
77         usable_recipe[2][1] = items[4] or ''
78         usable_recipe[2][2] = items[5] or ''
79         usable_recipe[2][3] = items[6] or ''
80         usable_recipe[3][1] = items[7] or ''
81         usable_recipe[3][2] = items[8] or ''
82         usable_recipe[3][3] = items[9] or ''
83     end
84     return(usable_recipe)
85 end
86
87 local map_group_to_item = {
88         ["coal"]  = "main:coal",
89         ["glass"] = "main:glass",
90         ["sand"]  = "main:sand",
91         ["stick"] = "main:stick",
92         ["stone"] = "main:cobble",
93         ["tree"]  = "main:tree",
94         ["wood"]  = "main:wood"
95 }
96
97 local get_if_group = function(item)
98         if item ~= nil and item:sub(1,6) == "group:" then
99                 local group_name = item:sub(7, item:len())
100                 local mapped_item = map_group_to_item[group_name]
101                 if mapped_item ~= nil then
102                         return(mapped_item)
103                 end
104         end
105         return(item)
106 end
107
108
109 local base_x = 0.75
110 local base_y = -0.5
111 local output_constant = 
112 "listcolors[#8b8a89;#c9c3c6;#3e3d3e;#000000;#FFFFFF]"..
113 "list[current_player;main;0,4.5;9,1;]"..   --hot bar
114 "list[current_player;main;0,6;9,3;9]"..    --main inventory
115 "button[5,3.5;1,1;toomanyitems.back;back]" --back button
116 local output
117 local recipe
118 local usable_recipe
119 local function create_craft_formspec(item)
120         --don't do air
121         if item == "" then
122                 return("")
123         end
124
125         recipe = minetest.get_craft_recipe(item)
126         
127         usable_table = recipe_converter(recipe.items, recipe.width)
128
129         output = output_constant
130         
131         if recipe.method == "normal" then
132                 if usable_table then
133                         --shaped (regular)
134                         if recipe.width > 0 then
135                                 for x = 1,3 do
136                                         for y = 1,3 do
137                                                 item = get_if_group(usable_table[x][y])
138                                                 if item then
139                                                         output = output.."item_image_button["..base_x+y..","..base_y+x..";1,1;"..item..";"..item..";]"
140                                                 else
141                                                         output = output.."item_image_button["..base_x+y..","..base_y+x..";1,1;;;]"
142                                                 end
143                                         end
144                                 end
145                         --shapeless
146                         else
147                                 local i = 1
148                                 for x = 1,3 do
149                                         for y = 1,3 do
150                                                 item = get_if_group(usable_table[i])
151                                                 if item then
152                                                         output = output.."item_image_button["..base_x+y..","..base_y+x..";1,1;"..item..";"..item..";]"
153                                                 else
154                                                         output = output.."item_image_button["..base_x+y..","..base_y+x..";1,1;;;]"
155                                                 end
156                                                 i = i + 1
157                                         end
158                                 end
159                         end
160                 end
161         elseif recipe.method == "cooking" then
162                 item = recipe.items[1]
163                 output = output.."item_image_button["..(base_x+2)..","..(base_y+1)..";1,1;"..item..";"..item..";]"
164                 output = output.."image[2.75,1.5;1,1;default_furnace_fire_fg.png]"
165         end
166         return(output)
167 end
168
169 local function cheat_button(name)
170         if pool[name] and pool[name].cheating then
171                 return "button[11.5,7.6;2,2;toomanyitems.cheat;cheat:on]"
172         elseif minetest.check_player_privs(name, {give = true}) then
173                 return "button[11.5,7.6;2,2;toomanyitems.cheat;cheat:off]"
174         else
175                 return ""
176         end
177 end
178
179
180 local form
181 local id
182 local inv
183 local item
184 local stack
185 local craft_inv
186 local name
187 local temp_pool
188 minetest.register_on_player_receive_fields(function(player, formname, fields)
189         name = player:get_player_name()
190         temp_pool = pool[name]
191
192         if formname == "" then
193                 form = base_inv
194                 id = ""
195         elseif formname == "crafting" then
196                 form = crafting_table_inv
197                 id = "crafting"
198         end
199         
200         --"next" button
201         if fields["toomanyitems.next"] then
202                 temp_pool.page = temp_pool.page + 1
203                 --page loops back to first
204                 if temp_pool.page > tmi_master_inventory.page_limit then
205                         temp_pool.page = 1
206                 end     
207                 minetest.show_formspec(name,id, form..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
208                 minetest.sound_play("lever", {to_player = name,gain=0.7})
209                 player:set_inventory_formspec(base_inv..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
210         --"prev" button
211         elseif fields["toomanyitems.prev"] then
212                 temp_pool.page = temp_pool.page - 1
213                 --page loops back to end
214                 if temp_pool.page < 1 then
215                         temp_pool.page = tmi_master_inventory.page_limit
216                 end     
217                 
218                 minetest.show_formspec(name,id, form..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
219                 minetest.sound_play("lever", {to_player = name,gain=0.7})
220                 player:set_inventory_formspec(base_inv..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
221         elseif fields["toomanyitems.back"] then
222
223                 minetest.show_formspec(name,id, form..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
224                 minetest.sound_play("lever", {to_player = name,gain=0.7})
225         --this resets the craft table
226         elseif fields.quit then
227                 inv = player:get_inventory()
228                 dump_craft(player)
229                 inv:set_width("craft", 2)
230                 inv:set_size("craft", 4)
231                 --reset the player inv
232                 --minetest.show_formspec(name,id, form..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
233         elseif fields["toomanyitems.cheat"] then
234                 --check if the player has the give priv
235                 if (not temp_pool.cheating and minetest.get_player_privs(name).give == true) or temp_pool.cheating == true then
236                         temp_pool.cheating = not temp_pool.cheating
237
238                         minetest.show_formspec(name,id, form..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
239                         minetest.sound_play("lever", {to_player = name,gain=0.7})
240                         player:set_inventory_formspec(base_inv..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
241                 else
242                         minetest.chat_send_player(name, "Sorry m8, server says I can't let you do that :(")
243                         minetest.sound_play("lever", {to_player = name,gain=0.7,pitch=0.7})
244                 end
245         --this is the "cheating" aka giveme function and craft recipe
246         elseif fields and type(fields) == "table" and string.match(next(fields),"toomanyitems.") then
247
248                 item = string.gsub(next(fields), "toomanyitems.", "")
249                 stack = ItemStack(item.." 64")
250                 inv = player:get_inventory()
251                 if temp_pool.cheating and minetest.get_player_privs(name).give then
252                         
253                         --room for item
254                         if inv and inv:room_for_item("main",stack) then
255                                 inv:add_item("main", stack)
256                                 minetest.sound_play("pickup", {to_player = name,gain=0.7,pitch = math.random(60,100)/100})
257                         --no room for item
258                         else
259                                 minetest.chat_send_player(name, "Might want to clear your inventory")
260                                 minetest.sound_play("lever", {to_player = name,gain=0.7,pitch=0.7})
261                         end
262
263                 --this is to get the craft recipe
264                 else
265                         craft_inv = create_craft_formspec(item)
266                         if craft_inv and craft_inv ~= "" then
267                                 minetest.show_formspec(name, id, tmi_master_inventory["page_"..temp_pool.page]..craft_inv..cheat_button(name))
268                                 minetest.sound_play("lever", {to_player = name,gain=0.7})
269                         end
270                 end
271
272         end
273 end)
274
275
276 --run through the items and then set the pages
277 local item_counter = 0
278 local page = 1
279 local x = 0
280 local y = 0
281
282 minetest.register_on_mods_loaded(function()
283
284 --sort all items (There is definitely a better way to do this)
285
286 --get all craftable items
287 local all_items_table = {}
288 for index,data in pairs(minetest.registered_items) do
289         if data.name ~= "" then
290                 local recipe = minetest.get_craft_recipe(data.name)
291                 --only put in craftable items
292                 if recipe.method then                   
293                         table.insert(all_items_table,data.name)
294                 end
295         end
296 end
297
298 table.sort(all_items_table)
299
300 --dump all the items in
301
302 tmi_master_inventory["page_"..page] = "size[17.2,8.75]background[-0.19,-0.25;9.41,9.49;crafting_inventory_workbench.png]"
303
304 for _,item in pairs(all_items_table) do
305         tmi_master_inventory["page_"..page] = tmi_master_inventory["page_"..page].."item_image_button["..(9.25+x)..","..y..";1,1;"..item..";toomanyitems."..item..";]"
306         x = x + 1
307         if x > 7 then
308                 x = 0
309                 y = y + 1
310         end
311         if y > 7 then
312                 y = 0
313                 page = page + 1
314                 tmi_master_inventory["page_"..page] = "size[17.2,8.75]background[-0.19,-0.25;9.41,9.49;crafting_inventory_workbench.png]"
315         end
316 end
317
318 --add buttons and labels
319 for i = 1,page do
320         --set the last page
321         tmi_master_inventory["page_"..i] = tmi_master_inventory["page_"..i].."button[9.25,7.6;2,2;toomanyitems.prev;prev]"..
322         "button[15.25,7.6;2,2;toomanyitems.next;next]"..
323         --this is +1 so it makes more sense
324         "label[13.75,8.25;page "..i.."/"..page.."]"
325 end
326
327 tmi_master_inventory.page_limit = page
328
329 --override crafting table
330 local name
331 local temp_pool
332
333 minetest.override_item("craftingtable:craftingtable", {
334          on_rightclick = function(pos, node, player, itemstack)
335                 name = player:get_player_name()
336                 temp_pool = pool[name]
337                 player:get_inventory():set_width("craft", 3)
338                 player:get_inventory():set_size("craft", 9)
339                 minetest.show_formspec(name, "crafting", crafting_table_inv..tmi_master_inventory["page_"..temp_pool.page]..cheat_button(name))
340         end
341 })
342 end)
343
344
345 --set new players inventory up
346 local name
347 local temp_pool
348 local inv
349 minetest.register_on_joinplayer(function(player)
350         name = player:get_player_name()
351         pool[name] = {}
352         temp_pool = pool[name]
353
354         temp_pool.page = 1
355         temp_pool.cheating = false
356
357         inv = player:get_inventory()
358         inv:set_width("craft", 2)
359         inv:set_width("main", 9)
360         inv:set_size("main", 9*4)
361         inv:set_size("craft", 4)
362
363         player:set_inventory_formspec(base_inv..tmi_master_inventory["page_1"]..cheat_button(name))
364
365         player:hud_set_hotbar_itemcount(9)
366         player:hud_set_hotbar_image("inventory_hotbar.png")
367         player:hud_set_hotbar_selected_image("hotbar_selected.png")
368 end)
369
370 local name
371 minetest.register_on_leaveplayer(function(player)
372         name = player:get_player_name()
373         pool[name] = nil
374 end)