22877b5aecb9f2e29dec3420c6e691d9ba032090
[oweals/minetest_game.git] / mods / creative / init.lua
1 -- minetest/creative/init.lua
2
3 local creative_inventory = {}
4 creative_inventory.creative_inventory_size = 0
5
6 -- Create detached creative inventory after loading all mods
7 minetest.after(0, function()
8         local inv = minetest.create_detached_inventory("creative", {
9                 allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
10                         if minetest.setting_getbool("creative_mode") then
11                                 return count
12                         else
13                                 return 0
14                         end
15                 end,
16                 allow_put = function(inv, listname, index, stack, player)
17                         return 0
18                 end,
19                 allow_take = function(inv, listname, index, stack, player)
20                         if minetest.setting_getbool("creative_mode") then
21                                 return -1
22                         else
23                                 return 0
24                         end
25                 end,
26                 on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
27                 end,
28                 on_put = function(inv, listname, index, stack, player)
29                 end,
30                 on_take = function(inv, listname, index, stack, player)
31                         print(player:get_player_name().." takes item from creative inventory; listname="..dump(listname)..", index="..dump(index)..", stack="..dump(stack))
32                         if stack then
33                                 print("stack:get_name()="..dump(stack:get_name())..", stack:get_count()="..dump(stack:get_count()))
34                         end
35                 end,
36         })
37         local creative_list = {}
38         for name,def in pairs(minetest.registered_items) do
39                 if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
40                                 and def.description and def.description ~= "" then
41                         table.insert(creative_list, name)
42                 end
43         end
44         table.sort(creative_list)
45         inv:set_size("main", #creative_list)
46         for _,itemstring in ipairs(creative_list) do
47                 local stack = ItemStack(itemstring)
48                 -- Make a stack of the right number of items
49                 local stack2 = nil
50                 if stack:get_stack_max() == 1 then
51                         stack2 = ItemStack(stack:get_name())
52                 else
53                         stack2 = ItemStack(stack:get_name().." "..stack:get_stack_max())
54                 end
55                 inv:add_item("main", stack2)
56         end
57         creative_inventory.creative_inventory_size = #creative_list
58         print("creative inventory size: "..dump(creative_inventory.creative_inventory_size))
59 end)
60
61 -- Create the trash field
62 local trash = minetest.create_detached_inventory("creative_trash", {
63         -- Allow the stack to be placed and remove it in on_put()
64         -- This allows the creative inventory to restore the stack
65         allow_put = function(inv, listname, index, stack, player)
66                 if minetest.setting_getbool("creative_mode") then
67                         return stack:get_count()
68                 else
69                         return 0
70                 end
71         end,
72         on_put = function(inv, listname, index, stack, player)
73                 inv:set_stack(listname, index, "")
74         end,
75 })
76 trash:set_size("main", 1)
77
78
79 creative_inventory.set_creative_formspec = function(player, start_i, pagenum)
80         pagenum = math.floor(pagenum)
81         local pagemax = math.floor((creative_inventory.creative_inventory_size-1) / (6*4) + 1)
82         player:set_inventory_formspec("size[13,7.5]"..
83                         --"image[6,0.6;1,2;player.png]"..
84                         "list[current_player;main;5,3.5;8,4;]"..
85                         "list[current_player;craft;8,0;3,3;]"..
86                         "list[current_player;craftpreview;12,1;1,1;]"..
87                         "list[detached:creative;main;0.3,0.5;4,6;"..tostring(start_i).."]"..
88                         "label[2.0,6.55;"..tostring(pagenum).."/"..tostring(pagemax).."]"..
89                         "button[0.3,6.5;1.6,1;creative_prev;<<]"..
90                         "button[2.7,6.5;1.6,1;creative_next;>>]"..
91                         "label[5,1.5;Trash:]"..
92                         "list[detached:creative_trash;main;5,2;1,1;]")
93 end
94 minetest.register_on_joinplayer(function(player)
95         -- If in creative mode, modify player's inventory forms
96         if not minetest.setting_getbool("creative_mode") then
97                 return
98         end
99         creative_inventory.set_creative_formspec(player, 0, 1)
100 end)
101 minetest.register_on_player_receive_fields(function(player, formname, fields)
102         if not minetest.setting_getbool("creative_mode") then
103                 return
104         end
105         -- Figure out current page from formspec
106         local current_page = 0
107         local formspec = player:get_inventory_formspec()
108         local start_i = string.match(formspec, "list%[detached:creative;main;[%d.]+,[%d.]+;[%d.]+,[%d.]+;(%d+)%]")
109         start_i = tonumber(start_i) or 0
110
111         if fields.creative_prev then
112                 start_i = start_i - 4*6
113         end
114         if fields.creative_next then
115                 start_i = start_i + 4*6
116         end
117
118         if start_i < 0 then
119                 start_i = start_i + 4*6
120         end
121         if start_i >= creative_inventory.creative_inventory_size then
122                 start_i = start_i - 4*6
123         end
124                 
125         if start_i < 0 or start_i >= creative_inventory.creative_inventory_size then
126                 start_i = 0
127         end
128
129         creative_inventory.set_creative_formspec(player, start_i, start_i / (6*4) + 1)
130 end)
131