Creative: Override the hand instead of re-registering
[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         -- Override the hand tool
44         minetest.override_item("", {
45                 range = 10,
46                 tool_capabilities = {
47                         full_punch_interval = 0.5,
48                         max_drop_level = 3,
49                         groupcaps = {
50                                 crumbly = caps,
51                                 cracky  = caps,
52                                 snappy  = caps,
53                                 choppy  = caps,
54                                 oddly_breakable_by_hand = caps,
55                                 -- dig_immediate group doesn't use value 1. Value 3 is instant dig
56                                 dig_immediate =
57                                         {times = {[2] = digtime, [3] = 0}, uses = 0, maxlevel = 256},
58                         },
59                         damage_groups = {fleshy = 10},
60                 }
61         })
62 end
63
64 -- Unlimited node placement
65 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
66         if placer and placer:is_player() then
67                 return creative.is_enabled_for(placer:get_player_name())
68         end
69 end)
70
71 -- Don't pick up if the item is already in the inventory
72 local old_handle_node_drops = minetest.handle_node_drops
73 function minetest.handle_node_drops(pos, drops, digger)
74         if not digger or not digger:is_player() or
75                 not creative.is_enabled_for(digger:get_player_name()) then
76                 return old_handle_node_drops(pos, drops, digger)
77         end
78         local inv = digger:get_inventory()
79         if inv then
80                 for _, item in ipairs(drops) do
81                         if not inv:contains_item("main", item, true) then
82                                 inv:add_item("main", item)
83                         end
84                 end
85         end
86 end