RealBadAngel
2013-02-03 fd26a83fcf953fd955dca3967205304c30e77b60
commit | author | age
a4a3c2 1 --data tables definitions
R 2 unified_inventory = {}
3 unified_inventory.players = {}
4 unified_inventory.current_page = {}
5 unified_inventory.current_index = {}
6 unified_inventory.items_list_size = 0
7 unified_inventory.items_list = {}
8 unified_inventory.filtered_items_list_size = {}
9 unified_inventory.filtered_items_list = {}
10 unified_inventory.activefilter = {}
11 unified_inventory.alternate = {}
12 unified_inventory.current_item = {}
13
14 -- default inventory page
15 unified_inventory.default = "craft"
16
17 -- homepos stuff
18 local home_gui = {}
19 local homepos = {}
20 unified_inventory.home_filename = minetest.get_worldpath()..'/unified_inventory_home'
21
22 -- Create detached creative inventory after loading all mods
23 minetest.after(0.01, function()
24     unified_inventory.items_list = {}
25     for name,def in pairs(minetest.registered_items) do
26         if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
27                 and def.description and def.description ~= "" then
28             table.insert(unified_inventory.items_list, name)
29         end
30     end
31     table.sort(unified_inventory.items_list)
32     unified_inventory.items_list_size = #unified_inventory.items_list
33     print ("Unified Inventory. inventory size: "..unified_inventory.items_list_size)
34 end)
35
36 -- register_on_joinplayer
37 minetest.register_on_joinplayer(function(player)
38     local player_name = player:get_player_name()
39     table.insert(unified_inventory.players, player_name)
40     unified_inventory.current_index[player_name] = 1
41     unified_inventory.filtered_items_list[player_name] = {}
42     unified_inventory.filtered_items_list[player_name] = unified_inventory.items_list
43     unified_inventory.filtered_items_list_size[player_name]=unified_inventory.items_list_size
44     unified_inventory.activefilter[player_name]=""
45     unified_inventory.apply_filter(player_name, "")
46     unified_inventory.alternate[player_name] = 1
47     unified_inventory.current_item[player_name] =nil
48     unified_inventory.set_inventory_formspec(player,unified_inventory.get_formspec(player, unified_inventory.default))
49
50 --crafting guide inventories    
51 local inv = minetest.create_detached_inventory(player:get_player_name().."craftrecipe",{
52     allow_put = function(inv, listname, index, stack, player)
53         return 0
54         end,
55         allow_take = function(inv, listname, index, stack, player)
56             return 0
57         end,
58         allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
59             return 0
60         end,
61     })
62     inv:set_size("output", 1)
63     inv:set_size("build", 3*3)
64
65 -- refill slot
66 unified_inventory.refill = minetest.create_detached_inventory(player_name.."refill", {
67     allow_put = function(inv, listname, index, stack, player)
68         if minetest.setting_getbool("creative_mode") then
69             return stack:get_count()
70         else
71             return 0
72         end
73     end,
74     on_put = function(inv, listname, index, stack, player)
75         inv:set_stack(listname, index, ItemStack(stack:get_name().." "..stack:get_stack_max()))
76     end,
77 })
78 unified_inventory.refill:set_size("main", 1)
79 end)
80
81 -- trash slot
82 unified_inventory.trash = minetest.create_detached_inventory("trash", {
83     allow_put = function(inv, listname, index, stack, player)
84         if minetest.setting_getbool("creative_mode") then
85             return stack:get_count()
86         else
87             return 0
88         end
89     end,
90     on_put = function(inv, listname, index, stack, player)
91         inv:set_stack(listname, index, nil)
92     end,
93 })
94 unified_inventory.trash:set_size("main", 1)
95
96 -- set_inventory_formspec
97 unified_inventory.set_inventory_formspec = function(player,formspec)
98     if player then
99         if minetest.setting_getbool("creative_mode") then
100             -- if creative mode is on then wait a bit
101             minetest.after(0.01,function()
102             player:set_inventory_formspec(formspec)
103             end)
104         else
105         player:set_inventory_formspec(formspec)
106         end
107     end
108 end
109
110 -- get_formspec
111 unified_inventory.get_formspec = function(player,page)
112     if player==nil then    return "" end
113     local player_name = player:get_player_name()
114     unified_inventory.current_page[player_name]=page
115     
116     local formspec = "size[14,10]"
eff76c 117
a4a3c2 118     -- player inventory
R 119     formspec = formspec .. "list[current_player;main;0,4.5;8,4;]"
eff76c 120
a4a3c2 121     -- main buttons
R 122         formspec = formspec .. "button[0,9;1.8,.5;craft;Craft]"
123         formspec = formspec .. "button[1.6,9;1.8,.5;craftguide;Craft Guide]"
124         formspec = formspec .. "button[3.2,9;1.8,.5;bags;Bags]"
125         formspec = formspec .. "button[4.8,9;1.8,.5;misc;Misc.]"
eff76c 126
a4a3c2 127     --controls to flip items pages
R 128         local start_x=9.2
129         formspec = formspec .. "button["..(start_x+.6*0)..",9;.8,.5;start_list;|<]"
130         formspec = formspec .. "button["..(start_x+.6*1)..",9;.8,.5;rewind3;<<]"
131         formspec = formspec .. "button["..(start_x+.6*2)..",9;.8,.5;rewind1;<]"
132         formspec = formspec .. "button["..(start_x+.6*3)..",9;.8,.5;forward1;>]"
133         formspec = formspec .. "button["..(start_x+.6*4)..",9;.8,.5;forward3;>>]"
134         formspec = formspec .. "button["..(start_x+.6*5)..",9;.8,.5;end_list;>|]"
135     
eff76c 136     -- search box
a4a3c2 137         formspec = formspec .. "field[9.195,8.325;3,1;searchbox;;]"
eff76c 138         formspec = formspec .. "button[12,8;1.2,1;searchbutton;Search]"
R 139
a4a3c2 140     -- craft page
R 141     if page=="craft" then
142         formspec = formspec.."label[0,0;Crafting]"
143         formspec = formspec.."list[current_player;craftpreview;6,1;1,1;]"
144         formspec = formspec.."list[current_player;craft;2,1;3,3;]"
145             if minetest.setting_getbool("creative_mode") then
146                 formspec = formspec.."label[0,2.5;Refill:]"
147                 formspec = formspec.."list[detached:"..player_name.."refill;main;0,3;1,1;]"
148                 formspec = formspec.."label[7,2.5;Trash:]"
149                 formspec = formspec.."list[detached:trash;main;7,3;1,1;]"
150             end
151         end
eff76c 152
a4a3c2 153     -- craft guide page
R 154     if page=="craftguide" then
155         formspec = formspec.."label[0,0;Crafting Guide]"
156         formspec = formspec.."list[detached:"..player_name.."craftrecipe;build;2,1;3,3;]"
157         formspec = formspec.."list[detached:"..player_name.."craftrecipe;output;6,1;1,1;]"
158         formspec = formspec.."label[2,0.5;Input:]"
159         formspec = formspec.."label[6,0.5;Output:]"
160         formspec = formspec.."label[6,2.6;Method:]"
161         local item_name=unified_inventory.current_item[player_name]
162         if item_name then
163             formspec = formspec.."label[2,0;"..item_name.."]"    
164             local alternates = 0
165             local alternate = unified_inventory.alternate[player_name]
166             local crafts = crafts_table[item_name]
eff76c 167
a4a3c2 168             if crafts ~= nil then
R 169                 alternates = #crafts
170                 local craft = crafts[alternate]
171                 local method = "Crafting"
172                 if craft.type == "shapeless" then
173                 method="Crafting"
174                 end    
175                 if craft.type == "cooking" then
176                 method="Cooking"
177                 end    
178                 if craft.type == "fuel" then
179                 method="Fuel"
180                 end    
181                 if craft.type == "grinding" then
182                 method="Grinding"
183                 end    
184                 if craft.type == "alloy" then
185                 method="Alloy cooking"
186                 end    
187                 formspec = formspec.."label[6,3;"..method.."]"
188             end
189             
190             if alternates > 1 then
191             formspec = formspec.."label[0,2.6;Recipe "..tostring(alternate).." of "..tostring(alternates).."]"
192             formspec = formspec.."button[0,3.15;2,1;alternate;Alternate]"
193             end
194         end
195     end
196         
197     -- bags
198     if page=="bags" then
199     formspec = formspec.."label[0,0;Bags]"        
200     formspec=formspec.."button[0,2;2,0.5;bag1;Bag 1]"
201     formspec=formspec.."button[2,2;2,0.5;bag2;Bag 2]"
202     formspec=formspec.."button[4,2;2,0.5;bag3;Bag 3]"
203     formspec=formspec.."button[6,2;2,0.5;bag4;Bag 4]"
204     formspec=formspec.."list[detached:"..player_name.."_bags;bag1;0.5,1;1,1;]"
205     formspec=formspec.."list[detached:"..player_name.."_bags;bag2;2.5,1;1,1;]"
206     formspec=formspec.."list[detached:"..player_name.."_bags;bag3;4.5,1;1,1;]"
207     formspec=formspec.."list[detached:"..player_name.."_bags;bag4;6.5,1;1,1;]"
208         end
209     
210     for i=1,4 do
211         if page=="bag"..i then
212             local image = player:get_inventory():get_stack("bag"..i, 1):get_definition().inventory_image
213             formspec=formspec.."image[7,0;1,1;"..image.."]"
214             formspec=formspec.."list[current_player;bag"..i.."contents;0,1;8,3;]"
215         end
216     end
217     
218     -- Miscellaneous
219     if page=="misc" then
220         formspec = formspec.."label[0,0;Miscellaneous]"
221         formspec=formspec.."button[0,1;2,0.5;home_gui_set;Set Home]"
222         formspec=formspec.."button_exit[2,1;2,0.5;home_gui_go;Go Home]"
223         local home = homepos[player_name]
224         if home ~= nil then
225         formspec = formspec
226             formspec=formspec.."label[4,.9;Home set to:]"
227             formspec=formspec.."label[5.7,.9;("..math.floor(home.x)..","..math.floor(home.y)..","..math.floor(home.z)..")]"
228         end    
229         if minetest.setting_getbool("creative_mode") then
230             formspec=formspec.."button[0,2;2,0.5;misc_set_day;Set Day]"
231             formspec=formspec.."button[2,2;2,0.5;misc_set_night;Set Night]"
232         end
233     end
234     
235     --Items list
236     local list_index=unified_inventory.current_index[player_name]
237     local page=math.floor(list_index / (80) + 1)
238     local pagemax = math.floor((unified_inventory.filtered_items_list_size[player_name]-1) / (80) + 1)
239     local image
240     local item={}
241     for y=0,9,1 do
242     for x=0,7,1 do
243         name=unified_inventory.filtered_items_list[player_name][list_index]    
244         if minetest.registered_items[name] then
245         formspec=formspec.."item_image_button["..(8.2+x*.7)..","..(1+y*.7)..";.81,.81;"..name..";item_button"..list_index..";]"
246         list_index=list_index+1
247         end
248     end
249     end    
250     formspec=formspec.."label[8.2,0;Page:]"
251     formspec=formspec.."label[9,0;"..page.." of "..pagemax.."]"
252     formspec=formspec.."label[8.2,0.4;Filter:]"
253     formspec=formspec.."label[9,0.4;"..unified_inventory.activefilter[player_name].."]"
254     return formspec
255 end
256
257 -- register_on_player_receive_fields
258 minetest.register_on_player_receive_fields(function(player, formname, fields)
259     local player_name = player:get_player_name()
260     
261     -- main buttons
262     if fields.craft then
263         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"craft"))
264         return
265     end
266     
267     if fields.craftguide then
268         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"craftguide"))
269         return
270     end
271     
272     if fields.bags then
273         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"bags"))
274         return
275     end
276     
277     if fields.misc then
278         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"misc"))
279         return
280     end
281     
282     -- bags
283     for i=1,4 do
284         local page = "bag"..i
285         if fields[page] then
286             if player:get_inventory():get_stack(page, 1):get_definition().groups.bagslots==nil then
287                 page = "bags"
288             end
289             unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,page))
290             return
291         end
292     end
293     
294     -- Miscellaneous
295     if fields.home_gui_set then
296         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"misc"))
297         unified_inventory.set_home(player, player:getpos())
298     end
299     if fields.home_gui_go then
300         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"craft"))
301         unified_inventory.go_home(player)
302     end
303     if fields.misc_set_day then
304         if minetest.get_player_privs(player_name).settime==true then 
305         minetest.env:set_timeofday((6000 % 24000) / 24000)
306         minetest.chat_send_player(player_name, "Time of day set to 6am")
307         else
308         minetest.chat_send_player(player_name, "You don't have settime priviledge!")
309         end
310     end
311     if fields.misc_set_night then
312         if minetest.get_player_privs(player_name).settime==true then     
313         minetest.env:set_timeofday((21000 % 24000) / 24000)
314         minetest.chat_send_player(player_name, "Time of day set to 9pm")
315         else
316         minetest.chat_send_player(player_name, "You don't have settime priviledge!")    
317         end    
318     end
319     
320     -- Inventory page controls
321     local start=math.floor(unified_inventory.current_index[player_name]/80 +1 )
322     local start_i=start
323     local pagemax = math.floor((unified_inventory.filtered_items_list_size[player_name]-1) / (80) + 1)
324     
325     if fields.start_list then
326         start_i = 1
327     end
328     if fields.rewind1 then
329         start_i = start_i - 1
330     end
331     if fields.forward1 then
332         start_i = start_i + 1
333     end
334     if fields.rewind3 then
335         start_i = start_i - 3
336     end
337     if fields.forward3 then
338         start_i = start_i + 3
339     end
340     if fields.end_list then
341         start_i = pagemax
342     end
343     if start_i < 1 then
344         start_i = 1
345     end
346     if start_i > pagemax then
347         start_i =  pagemax
348     end
349     if not (start_i    ==start) then
350         unified_inventory.current_index[player_name] = (start_i-1)*80+1
351         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,unified_inventory.current_page[player_name]))
352         end
353     
354     -- Item list buttons
355     local list_index=unified_inventory.current_index[player_name]
356     local page=unified_inventory.current_page[player_name]
357     for i=0,80,1 do
358         local button="item_button"..list_index
359         if fields[button] then 
360             if minetest.setting_getbool("creative_mode")==false then
361                 unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,"craftguide"))
362                 page="craftguide"
363                 end            
364             if page=="craftguide" then 
365                 unified_inventory.current_item[player_name] = unified_inventory.filtered_items_list[player_name][list_index] 
366                 unified_inventory.alternate[player_name] = 1
367                 unified_inventory.update_recipe (player, unified_inventory.filtered_items_list[player_name][list_index], 1)
368                 unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,unified_inventory.current_page[player_name]))
369             else
370                 if minetest.setting_getbool("creative_mode") then
371                     local inv = player:get_inventory()
372                     dst_stack={}
373                     dst_stack["name"] = unified_inventory.filtered_items_list[player_name][list_index] 
374                     dst_stack["count"]=99
375                     if inv:room_for_item("main",dst_stack) then
376                     inv:add_item("main",dst_stack)
377                     end
378                 end    
379             end    
380         end    
381     list_index=list_index+1
382     end
383     
384     if fields.searchbutton then
385         unified_inventory.apply_filter(player_name, fields.searchbox)
386         unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,unified_inventory.current_page[player_name]))
387     end    
388     
389     -- alternate button
390     if fields.alternate then
391         local item_name=unified_inventory.current_item[player_name]
392         if item_name then
393             local alternates = 0
394             local alternate=unified_inventory.alternate[player_name]
395             local crafts = crafts_table[item_name]
396             if crafts ~= nil then
397                 alternates = #crafts
398             end
399             if alternates > 1 then
400             alternate=alternate+1
401             if alternate>alternates then
402                 alternate=1
403             end
404             unified_inventory.alternate[player_name]=alternate        
405             unified_inventory.update_recipe (player, unified_inventory.current_item[player_name], alternate)
406             unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,unified_inventory.current_page[player_name]))
407             end
408         end    
409     end        
410 end)
411
412 -- load_home
413 local load_home = function()
414     local input = io.open(unified_inventory.home_filename..".home", "r")
415     if input then
416         while true do
417             local x = input:read("*n")
418             if x == nil then
419                 break
420             end
421             local y = input:read("*n")
422             local z = input:read("*n")
423             local name = input:read("*l")
424             homepos[name:sub(2)] = {x = x, y = y, z = z}
425         end
426         io.close(input)
427     else
428         homepos = {}
429     end
430 end
431 load_home() -- run it now
432
433 -- set_home
434 unified_inventory.set_home = function(player, pos)
435     homepos[player:get_player_name()] = pos
436     -- save the home data from the table to the file
437     local output = io.open(unified_inventory.home_filename..".home", "w")
438     for k, v in pairs(homepos) do
439         if v ~= nil then
440             output:write(math.floor(v.x).." "..math.floor(v.y).." "..math.floor(v.z).." "..k.."\n")
441         end
442     end
443     io.close(output)
444 end
445
446 -- go_home 
447 unified_inventory.go_home = function(player)
448     local pos = homepos[player:get_player_name()]
449     if pos~=nil then
450         player:setpos(pos)
451     end
452 end
453
454 --apply filter to the inventory list (create filtered copy of full one)
455 unified_inventory.apply_filter = function(player_name,filter)
456     local size=0
457     local str_temp1=string.lower(filter)
458     local str_temp2
459     local str_temp3
460     unified_inventory.filtered_items_list[player_name]={}
461     for name,def in pairs(minetest.registered_items) do
462         if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
463                 and def.description and def.description ~= "" then
464             str_temp2=string.lower(def.name)
465             str_temp3=string.lower(def.description)
466             if string.find(str_temp2, str_temp1) or string.find(str_temp3, str_temp1) then
467                 table.insert(unified_inventory.filtered_items_list[player_name], name)
468                 size=size+1
469             end
470         end
471     
472     end
473     table.sort(unified_inventory.filtered_items_list[player_name])
474     unified_inventory.filtered_items_list_size[player_name]=size
475     unified_inventory.current_index[player_name]=1    
476     unified_inventory.activefilter[player_name]=filter
477     unified_inventory.set_inventory_formspec(player, unified_inventory.get_formspec(player,unified_inventory.current_page[player_name]))
478 end
479
480
481 -- update_recipe
482 unified_inventory.update_recipe = function(player, stack_name, alternate)
483     --print("Lookup:"..stack_name)
484     local inv = minetest.get_inventory({type="detached", name=player:get_player_name().."craftrecipe"})    
485     for i=0,inv:get_size("build"),1 do
486         inv:set_stack("build", i, nil)
487     end
488     inv:set_stack("cook", 1, nil)
489     inv:set_stack("fuel", 1, nil)
490
491     inv:set_stack("output", 1, stack_name)
492     local def
493     alternate = tonumber(alternate) or 1
494     local crafts = crafts_table[stack_name]
495     if crafts == nil then
496         --minetest.chat_send_player(player:get_player_name(), "no recipe available for "..stack_name)
497         return
498     end
499     if alternate < 1 or alternate > #crafts then
500         alternate = 1
501     end
502     local craft = crafts[alternate]
503     --print (dump(craft))
504     --minetest.chat_send_player(player:get_player_name(), "recipe for "..stack_name..": "..dump(craft))
505     
506     local itemstack = ItemStack(craft.output)
507     inv:set_stack("output", 1, itemstack)
508
509     -- cook, fuel, grinding recipes
510     if craft.type == "cooking" or craft.type == "fuel" or craft.type == "grinding" then
511         def=unified_inventory.find_item_def(craft.recipe)
512         if def then
513             inv:set_stack("build", 1, def)
514         end
515         return 
516     end
517     
518     -- build (shaped or shapeless)
519     if craft.recipe[1] then
520         def=unified_inventory.find_item_def(craft.recipe[1])
521         if def then
522             inv:set_stack("build", 1, def)
523         else
524             def=unified_inventory.find_item_def(craft.recipe[1][1])
525             if def then
526                 inv:set_stack("build", 1, def)
527             end
528             def=unified_inventory.find_item_def(craft.recipe[1][2])
529             if def then
530                 inv:set_stack("build", 2, def)
531             end
532             def=unified_inventory.find_item_def(craft.recipe[1][3])
533             if def then
534                 inv:set_stack("build", 3, def)
535             end
536         end
537     end
538     if craft.recipe[2] then
539         def=unified_inventory.find_item_def(craft.recipe[2])
540         if def then
541             inv:set_stack("build", 2, def)
542         else
543             def=unified_inventory.find_item_def(craft.recipe[2][1])
544             if def then
545                 inv:set_stack("build", 4, def)
546             end
547             def=unified_inventory.find_item_def(craft.recipe[2][2])
548             if def then
549                 inv:set_stack("build", 5, def)
550             end
551             def=unified_inventory.find_item_def(craft.recipe[2][3])
552             if def then
553                 inv:set_stack("build", 6, def)
554             end
555         end
556     end
557     
558     if craft.recipe[3] then
559         def=unified_inventory.find_item_def(craft.recipe[3])
560         if def then
561             inv:set_stack("build", 3, def)
562         else
563             def=unified_inventory.find_item_def(craft.recipe[3][1])
564             if def then
565                 inv:set_stack("build", 7, def)
566             end
567             def=unified_inventory.find_item_def(craft.recipe[3][2])
568             if def then
569                 inv:set_stack("build", 8, def)
570             end
571             def=unified_inventory.find_item_def(craft.recipe[3][3])
572             if def then
573                 inv:set_stack("build", 9, def)
574             end
575         end
576     end
577     if craft.recipe[4] then
578         def=unified_inventory.find_item_def(craft.recipe[4])
579         if def then
580             inv:set_stack("build", 4, def)
581         end
582     end
583     if craft.recipe[5] then
584         def=unified_inventory.find_item_def(craft.recipe[5])
585         if def then
586             inv:set_stack("build", 5, def)
587         end
588     end
589     if craft.recipe[6] then
590         def=unified_inventory.find_item_def(craft.recipe[6])
591         if def then
592             inv:set_stack("build", 6, def)
593         end
594     end
595     if craft.recipe[7] then
596         def=unified_inventory.find_item_def(craft.recipe[7])
597         if def then
598             inv:set_stack("build", 7, def)
599         end
600     end
601     if craft.recipe[8] then
602         def=unified_inventory.find_item_def(craft.recipe[8])
603         if def then
604             inv:set_stack("build", 8, def)
605         end
606     end
607     if craft.recipe[9] then
608         def=unified_inventory.find_item_def(craft.recipe[9])
609         if def then
610             inv:set_stack("build", 9, def)
611         end
612     end
613 end
614
615 unified_inventory.find_item_def = function(def1)
616 if type(def1)=="string" then
617     if string.find(def1, "group:") then
618         def1=string.gsub(def1, "group:", "")
619         def1=string.gsub(def1, '\"', "")
620         for name,def in pairs(minetest.registered_items) do
621                 if def.groups[def1] == 1 and def.groups.not_in_creative_inventory ~= 1 then
622                     return def
623                 end
624         end
625     else
626     return def1
627     end
628 end
629 return nil
630 end