Fix potential crash when few loot items are registered
[oweals/minetest_game.git] / mods / creative / init.lua
1 creative = {}
2
3 local function update_sfinv(name)
4         minetest.after(0, function()
5                 local player = minetest.get_player_by_name(name)
6                 if player then
7                         if sfinv.get_page(player):sub(1, 9) == "creative:" then
8                                 sfinv.set_page(player, sfinv.get_homepage_name(player))
9                         else
10                                 sfinv.set_player_inventory_formspec(player)
11                         end
12                 end
13         end)
14 end
15
16 minetest.register_privilege("creative", {
17         description = "Allow player to use creative inventory",
18         give_to_singleplayer = false,
19         give_to_admin = false,
20         on_grant = update_sfinv,
21         on_revoke = update_sfinv,
22 })
23
24 local creative_mode_cache = minetest.settings:get_bool("creative_mode")
25
26 function creative.is_enabled_for(name)
27         return creative_mode_cache or
28                 minetest.check_player_privs(name, {creative = true})
29 end
30
31 dofile(minetest.get_modpath("creative") .. "/inventory.lua")
32
33 if creative_mode_cache then
34         -- Dig time is modified according to difference (leveldiff) between tool
35         -- 'maxlevel' and node 'level'. Digtime is divided by the larger of
36         -- leveldiff and 1.
37         -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been
38         -- increased such that nodes of differing levels have an insignificant
39         -- effect on digtime.
40         local digtime = 42
41         local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256}
42
43         minetest.register_item(":", {
44                 type = "none",
45                 wield_image = "wieldhand.png",
46                 wield_scale = {x = 1, y = 1, z = 2.5},
47                 range = 10,
48                 tool_capabilities = {
49                         full_punch_interval = 0.5,
50                         max_drop_level = 3,
51                         groupcaps = {
52                                 crumbly = caps,
53                                 cracky  = caps,
54                                 snappy  = caps,
55                                 choppy  = caps,
56                                 oddly_breakable_by_hand = caps,
57                         },
58                         damage_groups = {fleshy = 10},
59                 }
60         })
61 end
62
63 -- Unlimited node placement
64 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
65         if placer and placer:is_player() then
66                 return creative.is_enabled_for(placer:get_player_name())
67         end
68 end)
69
70 -- Don't pick up if the item is already in the inventory
71 local old_handle_node_drops = minetest.handle_node_drops
72 function minetest.handle_node_drops(pos, drops, digger)
73         if not digger or not digger:is_player() or
74                 not creative.is_enabled_for(digger:get_player_name()) then
75                 return old_handle_node_drops(pos, drops, digger)
76         end
77         local inv = digger:get_inventory()
78         if inv then
79                 for _, item in ipairs(drops) do
80                         if not inv:contains_item("main", item, true) then
81                                 inv:add_item("main", item)
82                         end
83                 end
84         end
85 end