]> git.lizzy.rs Git - Crafter.git/blob - mods/hopper/utility.lua
Pushing a test for fall damage calculations
[Crafter.git] / mods / hopper / utility.lua
1 local S = minetest.get_translator("hopper")
2 -- Target inventory retrieval
3
4 -- looks first for a registration matching the specific node name, then for a registration
5 -- matching group and value, then for a registration matching a group and *any* value
6 hopper.get_registered_inventories_for = function(target_node_name)
7         local output = hopper.containers[target_node_name]
8         if output ~= nil then return output end
9
10         local target_def = minetest.registered_nodes[target_node_name]
11         if target_def == nil or target_def.groups == nil then return nil end
12
13         for group, value in pairs(target_def.groups) do
14                 local registered_group = hopper.groups[group]
15                 if registered_group ~= nil then
16                         output = registered_group[value]
17                         if output ~= nil then return output end
18                         output = registered_group["all"]
19                         if output ~= nil then return output end
20                 end
21         end
22
23         return nil
24 end
25
26 hopper.get_eject_button_texts = function(pos, loc_X, loc_Y)
27         if not hopper.config.eject_button_enabled then return "" end
28
29         local eject_button_text, eject_button_tooltip
30         if minetest.get_meta(pos):get_string("eject") == "true" then
31                 eject_button_text = S("Don't\nEject")
32                 eject_button_tooltip = S("This hopper is currently set to eject items from its output\neven if there isn't a compatible block positioned to receive it.\nClick this button to disable this feature.")
33         else
34                 eject_button_text = S("Eject\nItems")
35                 eject_button_tooltip = S("This hopper is currently set to hold on to item if there\nisn't a compatible block positioned to receive it.\nClick this button to have it eject items instead.")
36         end
37         return "button_exit["..loc_X..","..loc_Y..";1,1;eject;"..eject_button_text.."]tooltip[eject;"..eject_button_tooltip.."]"
38 end
39
40 hopper.get_string_pos = function(pos)
41         return pos.x .. "," .. pos.y .. "," ..pos.z
42 end
43
44 -- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
45 hopper.metal_sounds = main.stoneSound()
46
47 -------------------------------------------------------------------------------------------
48 -- Inventory transfer functions
49
50 local delay = function(x)
51         return (function() return x end)
52 end
53
54 local get_placer = function(player_name)
55         if player_name ~= "" then
56                 return minetest.get_player_by_name(player_name) or {
57                         is_player = delay(true),
58                         get_player_name = delay(player_name),
59                         is_fake_player = ":hopper",
60                         get_wielded_item = delay(ItemStack(nil))
61                 }
62         end
63         return nil
64 end
65
66 -- Used to remove items from the target block and put it into the hopper's inventory
67 hopper.take_item_from = function(hopper_pos, target_pos, target_node, target_inventory_name)
68         if target_inventory_name == nil then
69                 return
70         end
71         local target_def = minetest.registered_nodes[target_node.name]
72         if not target_def then
73                 return
74         end
75
76         --hopper inventory
77         local hopper_meta = minetest.get_meta(hopper_pos);
78         local hopper_inv = hopper_meta:get_inventory()
79         local placer = get_placer(hopper_meta:get_string("placer"))
80
81         --source inventory
82         local target_inv = minetest.get_meta(target_pos):get_inventory()
83         local target_inv_size = target_inv:get_size(target_inventory_name)
84         if target_inv:is_empty(target_inventory_name) == false then
85                 for i = 1,target_inv_size do
86                         local stack = target_inv:get_stack(target_inventory_name, i)
87                         local item = stack:get_name()
88                         if item ~= "" then
89                                 if hopper_inv:room_for_item("main", item) then
90                                         local stack_to_take = stack:take_item(1)
91                                         if target_def.allow_metadata_inventory_take == nil
92                                           or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
93                                           or target_def.allow_metadata_inventory_take(target_pos, target_inventory_name, i, stack_to_take, placer) > 0 then
94                                                 target_inv:set_stack(target_inventory_name, i, stack)
95                                                 --add to hopper
96                                                 hopper_inv:add_item("main", stack_to_take)
97                                                 if target_def.on_metadata_inventory_take ~= nil and placer ~= nil then
98                                                         target_def.on_metadata_inventory_take(target_pos, target_inventory_name, i, stack_to_take, placer)
99                                                 end
100                                                 break
101                                         end
102                                 end
103                         end
104                 end
105         end
106 end
107
108 -- Used to put items from the hopper inventory into the target block
109 hopper.send_item_to = function(hopper_pos, target_pos, target_node, target_inventory_name, filtered_items)
110         local hopper_meta = minetest.get_meta(hopper_pos)
111         local target_def = minetest.registered_nodes[target_node.name]
112         if not target_def then
113                 return false
114         end
115
116         local eject_item = hopper.config.eject_button_enabled and hopper_meta:get_string("eject") == "true" and target_def.buildable_to
117
118         if not eject_item and not target_inventory_name then
119                 return false
120         end
121
122         --hopper inventory
123         local hopper_meta = minetest.get_meta(hopper_pos);
124         local hopper_inv = hopper_meta:get_inventory()
125         if hopper_inv:is_empty("main") == true then
126                 return false
127         end
128         local hopper_inv_size = hopper_inv:get_size("main")
129         local placer = get_placer(hopper_meta:get_string("placer"))
130
131         --target inventory
132         local target_inv = minetest.get_meta(target_pos):get_inventory()
133
134         for i = 1,hopper_inv_size do
135                 local stack = hopper_inv:get_stack("main", i)
136                 local item = stack:get_name()
137                 if item ~= "" and (filtered_items == nil or filtered_items[item]) then
138                         if target_inventory_name then
139                                 if target_inv:room_for_item(target_inventory_name, item) then
140                                         local stack_to_put = stack:take_item(1)
141                                         if target_def.allow_metadata_inventory_put == nil
142                                         or placer == nil -- backwards compatibility, older versions of this mod didn't record who placed the hopper
143                                         or target_def.allow_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer) > 0 then
144                                                 hopper_inv:set_stack("main", i, stack)
145                                                 --add to target node
146                                                 target_inv:add_item(target_inventory_name, stack_to_put)
147                                                 if target_def.on_metadata_inventory_put ~= nil and placer ~= nil then
148                                                         target_def.on_metadata_inventory_put(target_pos, target_inventory_name, i, stack_to_put, placer)
149                                                 end
150                                                 return true
151                                         end
152                                 end
153                         elseif eject_item then
154                                 local stack_to_put = stack:take_item(1)
155                                 minetest.add_item(target_pos, stack_to_put)
156                                 hopper_inv:set_stack("main", i, stack)
157                                 return true
158                         end
159                 end
160         end
161         return false
162 end