Switch to Nodetimers, Enable shift+click
[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 meta = minetest.get_meta(pos)
71 local inv = meta:get_inventory()
72 return inv:is_empty("main")
73 end
74
75 local function start_timer(pos)
76 local timer = minetest.get_node_timer(pos)
77 timer:start(update_interval)
78 end
79
80 local tube = {
81 insert_object = function(pos, node, stack, direction)
82 local meta = minetest.get_meta(pos)
83 local inv = meta:get_inventory()
84 start_timer(pos)
85 if node.name == "feedlot:milker" then
86 if stack:get_name() == "bucket:bucket_empty" and inv:room_for_item("bucket", stack) then
87 inv:add_item("bucket", stack)
88 return ItemStack(nil)
89 else
90 return stack
91 end
92 end
93
94 if inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty" then
95 inv:add_item("main", stack)
96 return ItemStack(nil)
97 else
98 return stack
99 end
100 end,
101 can_insert = function(pos, node, stack, direction)
102 local meta = minetest.get_meta(pos)
103 local inv = meta:get_inventory()
104 if node.name == "feedlot:milker" then
105 if stack:get_name() == "bucket:bucket_empty" then
106 return inv:room_for_item("bucket", stack)
107 else
108 return false
109 end
110 else
111 return inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty"
112 end
113 end,
114 input_inventory = "main",
115 connect_sides = {left = 0, right = 0, front = 0, back = 0, top = 0, bottom = 1}}
116
117
118 local function is_mob(obj)
119 return obj.get_luaentity and obj:get_luaentity().name and string.sub(obj:get_luaentity().name,1,string.len("mob"))=="mob"
120 end
121
122
123 local function feed_animals (pos, elapsed)
124 local node = minetest.get_node(pos)
125 local meta = minetest.get_meta(pos)
126 local inv = meta:get_inventory()
127
128
129 local fake_player = feedlotFakePlayer.create(pos, "fake_player")
130
131 local radius = 3
132 if node.name == "feedlot:milker" then
133 radius = 5
134 if inv:is_empty("bucket") then
135 return false
136 end
137 else
138 if inv:is_empty("main") then
139 return false
140 end
141 end
142
143 local objs = minetest.get_objects_inside_radius(pos, radius)
144 for _,obj in ipairs(objs) do
145 ent = obj:get_luaentity()
146 if not obj:is_player() and obj:get_armor_groups().fleshy and obj:get_armor_groups().fleshy > 0 and is_mob(obj) then
147 if ent.on_rightclick then
148 if not (ent.horny and node.name == "feedlot:feedlot") then
149 if node.name == "feedlot:milker" and not inv:room_for_item("main", "mobs:bucket_milk") then
150 return false
151 end
152 obj:get_luaentity():on_rightclick(fake_player)
153 end
154 end
155 end
156 end
157 return true
158 end
159
160
161 minetest.register_node("feedlot:feedlot", {
162 description = "Feedlot",
163 tiles = {
164 "default_wood.png^feedlot_feed.png",
165 "default_wood.png",
166 "default_wood.png",
167 "default_wood.png",
168 "default_wood.png",
169 "default_wood.png"
170 },
171 drawtype = "nodebox",
172 paramtype = "light",
173 node_box = {
174 type = "fixed",
175 fixed = {
176 {-0.5, -0.5, -0.5, 0.5, -0.1875, -0.4375}, -- NodeBox6
177 {0.4375, -0.5, -0.5, 0.5, -0.1875, 0.5}, -- NodeBox7
178 {-0.5, -0.5, 0.4375, 0.5, -0.1875, 0.5}, -- NodeBox8
179 {-0.5, -0.5, -0.5, -0.4375, -0.1875, 0.5}, -- NodeBox9
180 {-0.4375, -0.5, -0.4375, 0.4375, -0.375, 0.4375}, -- NodeBox10
181 }
182 },
183 on_metadata_inventory_put = function(pos, listname, index, stack, player)
184 start_timer(pos)
185 end,
186 on_rightclick = function(pos, node, player, itemstack, pointed_thing)
187 start_timer(pos)
188 end,
189 allow_metadata_inventory_put = function (_, _, _, stack, _)
190 if stack:get_name() == "bucket:bucket_empty" then
191 return 0
192 else
193 return stack:get_count()
194 end
195 end,
196 on_construct = on_construct,
197 can_dig = can_dig,
198 groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
199 tube = tube,
200 on_timer = feed_animals
201 })
202 minetest.register_node("feedlot:milker", {
203 description = "Milker",
204 tiles = {
205 "feedlot_milker_top.png",
206 "feedlot_milker_top.png",
207 "feedlot_milker_side.png",
208 "feedlot_milker_side.png",
209 "feedlot_milker_side.png",
210 "feedlot_milker_side.png",
211 },
212 paramtype = "light",
213 allow_metadata_inventory_put = function (_, listname, _, stack, _)
214 if listname == "bucket" and stack:get_name() == "bucket:bucket_empty" then
215 return stack:get_count()
216 else
217 return 0
218 end
219 end,
220 allow_metadata_inventory_move = function (_, _, _, dst, _, count)
221 return 0
222 end,
223 on_construct = on_construct,
224 can_dig = can_dig,
225 groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1},
226 tube = tube,
227 on_timer = feed_animals,
228 on_metadata_inventory_put = function(pos, listname, index, stack, player)
229 start_timer(pos)
230 end,
231 on_rightclick = function(pos, node, player, itemstack, pointed_thing)
232 start_timer(pos)
233 end,
234
235 })
236
237
238
239
240
241 minetest.register_craft({
242 output = "feedlot:feedlot",
243 recipe = {
244 {"","",""},
245 {"default:wood", "farming:seed_wheat", "default:wood"},
246 {"default:wood", "default:wood", "default:wood"}
247 }})
248 minetest.register_craft({
249 output = "feedlot:milker",
250 recipe = {
251 {"default:steel_ingot","","default:steel_ingot"},
252 {"default:steel_ingot", "bucket:bucket_empty", "default:steel_ingot"},
253 {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
254 }})