Forbid digging milkers with buckets in them
[feedlot.git] / init.lua
1 -- feedlot mod Copyright (C) 2017,2020 Gabriel PĂ©rez-Cerezo
2 -- This program is free software: you can redistribute it and/or modify
3 -- it under the terms of the GNU Affero General Public License as published by
4 -- the Free Software Foundation, either version 3 of the License, or
5 -- (at your option) any later version.
6
7 -- This program is distributed in the hope that it will be useful,
8 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
9 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 -- GNU Affero General Public License for more details.
11
12 -- You should have received a copy of the GNU Affero General Public License
13 -- along with this program. If not, see <https://www.gnu.org/licenses/>.
14
15
16
17 local modpath = minetest.get_modpath( "feedlot" )
18 dofile(modpath.."/fakeplayer.lua")
19
20 local update_interval = 5
21
22 local function get_formspec(pos)
23 local spos = pos.x .. "," ..pos.y .. "," .. pos.z
24 local xbg = default.gui_bg .. default.gui_bg_img .. default.gui_slots
25 -- local detached_inv = minetest.create_detached_inventory("mailbox_"..owner)
26 return "size[8,5.5]" .. xbg .. default.get_hotbar_bg(0, 1.5) ..
27 "label[0,0;Feedlot]" ..
28 "list[current_name;main;3.5,0;1,1;]" ..
29 "list[current_player;main;0,1.5;8,1;]" ..
30 "list[current_player;main;0,2.75;8,3;8]" ..
31 "listring[current_name;main]" ..
32 "listring[current_player;main]"
33 end
34 local function get_milker_formspec(pos)
35 return "size[8,8.5]"..
36 default.gui_bg..
37 default.gui_bg_img..
38 default.gui_slots..
39 "label[0,0;Milker]"..
40 "label[0,1;Buckets:]"..
41 "label[3.5,1;Milk:]"..
42 "list[current_name;bucket;1.5,1;1,1;]"..
43 "list[current_name;main;4.75,0.96;3,2;]"..
44 "list[current_player;main;0,4.25;8,1;]"..
45 "list[current_player;main;0,5.5;8,3;8]"..
46 "listring[current_player;main]"..
47 "listring[current_name;bucket]"..
48 "listring[current_player;main]"..
49 "listring[current_name;main]"..
50 "listring[current_player;main]"..
51 default.get_hotbar_bg(0, 4.25)
52 end
53
54
55 local function on_construct(pos)
56 local node = minetest.get_node(pos)
57 local meta = minetest.get_meta(pos)
58 local inv = meta:get_inventory()
59 if node.name == "feedlot:milker" then
60 meta:set_string("formspec", get_milker_formspec(pos))
61 inv:set_size("bucket", 1)
62 inv:set_size("main", 6)
63 else
64 meta:set_string("formspec", get_formspec(pos))
65 inv:set_size("main", 1)
66 end
67 end
68
69 local function can_dig(pos)
70 local node = minetest.get_node(pos)
71 local meta = minetest.get_meta(pos)
72 local inv = meta:get_inventory()
73 if node.name == "feedlot:milker" then
74 return inv:is_empty("main") and inv:is_empty("bucket")
75 end
76 return inv:is_empty("main")
77 end
78
79 local function start_timer(pos)
80 local timer = minetest.get_node_timer(pos)
81 timer:start(update_interval)
82 end
83
84 local tube = {
85 insert_object = function(pos, node, stack, direction)
86 local meta = minetest.get_meta(pos)
87 local inv = meta:get_inventory()
88 start_timer(pos)
89 if node.name == "feedlot:milker" then
90 if stack:get_name() == "bucket:bucket_empty" and inv:room_for_item("bucket", stack) then
91 inv:add_item("bucket", stack)
92 return ItemStack(nil)
93 else
94 return stack
95 end
96 end
97
98 if inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty" then
99 inv:add_item("main", stack)
100 return ItemStack(nil)
101 else
102 return stack
103 end
104 end,
105 can_insert = function(pos, node, stack, direction)
106 local meta = minetest.get_meta(pos)
107 local inv = meta:get_inventory()
108 if node.name == "feedlot:milker" then
109 if stack:get_name() == "bucket:bucket_empty" then
110 return inv:room_for_item("bucket", stack)
111 else
112 return false
113 end
114 else
115 return inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty"
116 end
117 end,
118 input_inventory = "main",
119 connect_sides = {left = 0, right = 0, front = 0, back = 0, top = 0, bottom = 1}}
120
121
122 local function is_mob(obj)
123 return obj.get_luaentity and obj:get_luaentity().name and string.sub(obj:get_luaentity().name,1,string.len("mob"))=="mob"
124 end
125
126
127 local function feed_animals (pos, elapsed)
128 local node = minetest.get_node(pos)
129 local meta = minetest.get_meta(pos)
130 local inv = meta:get_inventory()
131
132
133 local fake_player = feedlotFakePlayer.create(pos, "fake_player")
134
135 local radius = 3
136 if node.name == "feedlot:milker" then
137 radius = 5
138 if inv:is_empty("bucket") then
139 return false
140 end
141 else
142 if inv:is_empty("main") then
143 return false
144 end
145 end
146
147 local objs = minetest.get_objects_inside_radius(pos, radius)
148 for _,obj in ipairs(objs) do
149 ent = obj:get_luaentity()
150 if not obj:is_player() and obj:get_armor_groups().fleshy and obj:get_armor_groups().fleshy > 0 and is_mob(obj) then
151 if ent.on_rightclick then
152 if not (ent.horny and node.name == "feedlot:feedlot") then
153 if node.name == "feedlot:milker" and not inv:room_for_item("main", "mobs:bucket_milk") then
154 return false
155 end
156 obj:get_luaentity():on_rightclick(fake_player)
157 end
158 end
159 end
160 end
161 return true
162 end
163
164
165 minetest.register_node("feedlot:feedlot", {
166 description = "Feedlot",
167 tiles = {
168 "default_wood.png^feedlot_feed.png",
169 "default_wood.png",
170 "default_wood.png",
171 "default_wood.png",
172 "default_wood.png",
173 "default_wood.png"
174 },
175 drawtype = "nodebox",
176 paramtype = "light",
177 node_box = {
178 type = "fixed",
179 fixed = {
180 {-0.5, -0.5, -0.5, 0.5, -0.1875, -0.4375}, -- NodeBox6
181 {0.4375, -0.5, -0.5, 0.5, -0.1875, 0.5}, -- NodeBox7
182 {-0.5, -0.5, 0.4375, 0.5, -0.1875, 0.5}, -- NodeBox8
183 {-0.5, -0.5, -0.5, -0.4375, -0.1875, 0.5}, -- NodeBox9
184 {-0.4375, -0.5, -0.4375, 0.4375, -0.375, 0.4375}, -- NodeBox10
185 }
186 },
187 on_metadata_inventory_put = function(pos, listname, index, stack, player)
188 start_timer(pos)
189 end,
190 on_rightclick = function(pos, node, player, itemstack, pointed_thing)
191 start_timer(pos)
192 end,
193 allow_metadata_inventory_put = function (_, _, _, stack, _)
194 if stack:get_name() == "bucket:bucket_empty" then
195 return 0
196 else
197 return stack:get_count()
198 end
199 end,
200 on_construct = on_construct,
201 can_dig = can_dig,
202 groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
203 tube = tube,
204 on_timer = feed_animals
205 })
206 minetest.register_node("feedlot:milker", {
207 description = "Milker",
208 tiles = {
209 "feedlot_milker_top.png",
210 "feedlot_milker_top.png",
211 "feedlot_milker_side.png",
212 "feedlot_milker_side.png",
213 "feedlot_milker_side.png",
214 "feedlot_milker_side.png",
215 },
216 paramtype = "light",
217 allow_metadata_inventory_put = function (_, listname, _, stack, _)
218 if listname == "bucket" and stack:get_name() == "bucket:bucket_empty" then
219 return stack:get_count()
220 else
221 return 0
222 end
223 end,
224 allow_metadata_inventory_move = function (_, _, _, dst, _, count)
225 return 0
226 end,
227 on_construct = on_construct,
228 can_dig = can_dig,
229 groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
230 tube = tube,
231 on_timer = feed_animals,
232 on_metadata_inventory_put = function(pos, listname, index, stack, player)
233 start_timer(pos)
234 end,
235 on_rightclick = function(pos, node, player, itemstack, pointed_thing)
236 start_timer(pos)
237 end,
238
239 })
240
241
242
243
244
245 minetest.register_craft({
246 output = "feedlot:feedlot",
247 recipe = {
248 {"","",""},
249 {"default:wood", "farming:seed_wheat", "default:wood"},
250 {"default:wood", "default:wood", "default:wood"}
251 }})
252 minetest.register_craft({
253 output = "feedlot:milker",
254 recipe = {
255 {"default:steel_ingot","","default:steel_ingot"},
256 {"default:steel_ingot", "bucket:bucket_empty", "default:steel_ingot"},
257 {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
258 }})