From b8e18e15ac4c67fe8b8305efd4d2ac2965075107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= Date: Tue, 10 Mar 2020 22:37:59 +0100 Subject: Switch to Nodetimers, Enable shift+click Nodetimers should offer a big performance improvement, since they are not run on empty feedlots or milkers. To enable the node timer, items have to be inserted into the node, or the node has to be right-clicked. To enable shift+click, the node has to be dug and replaced. --- init.lua | 114 ++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 38 deletions(-) diff --git a/init.lua b/init.lua index a99b757..b5426ab 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ --- feedlot mod Copyright (C) 2017 Gabriel Pérez-Cerezo +-- feedlot mod Copyright (C) 2017,2020 Gabriel Pérez-Cerezo -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as published by -- the Free Software Foundation, either version 3 of the License, or @@ -17,6 +17,8 @@ local modpath = minetest.get_modpath( "feedlot" ) dofile(modpath.."/fakeplayer.lua") +local update_interval = 5 + local function get_formspec(pos) local spos = pos.x .. "," ..pos.y .. "," .. pos.z local xbg = default.gui_bg .. default.gui_bg_img .. default.gui_slots @@ -26,7 +28,7 @@ local function get_formspec(pos) "list[current_name;main;3.5,0;1,1;]" .. "list[current_player;main;0,1.5;8,1;]" .. "list[current_player;main;0,2.75;8,3;8]" .. --- "listring[detached:mailbox_" .. owner .. ";drop]" .. + "listring[current_name;main]" .. "listring[current_player;main]" end local function get_milker_formspec(pos) @@ -41,9 +43,10 @@ local function get_milker_formspec(pos) "list[current_name;main;4.75,0.96;3,2;]".. "list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,5.5;8,3;8]".. - "listring[current_name;dst]".. "listring[current_player;main]".. - "listring[current_name;src]".. + "listring[current_name;bucket]".. + "listring[current_player;main]".. + "listring[current_name;main]".. "listring[current_player;main]".. default.get_hotbar_bg(0, 4.25) end @@ -68,10 +71,17 @@ local function can_dig(pos) local inv = meta:get_inventory() return inv:is_empty("main") end + +local function start_timer(pos) + local timer = minetest.get_node_timer(pos) + timer:start(update_interval) +end + local tube = { insert_object = function(pos, node, stack, direction) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() + start_timer(pos) if node.name == "feedlot:milker" then if stack:get_name() == "bucket:bucket_empty" and inv:room_for_item("bucket", stack) then inv:add_item("bucket", stack) @@ -98,12 +108,56 @@ local tube = { return false end else - return inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty" + return inv:room_for_item("main", stack) and stack:get_name() ~= "bucket:bucket_empty" end end, input_inventory = "main", connect_sides = {left = 0, right = 0, front = 0, back = 0, top = 0, bottom = 1}} + +local function is_mob(obj) + return obj.get_luaentity and obj:get_luaentity().name and string.sub(obj:get_luaentity().name,1,string.len("mob"))=="mob" +end + + +local function feed_animals (pos, elapsed) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + + local fake_player = feedlotFakePlayer.create(pos, "fake_player") + + local radius = 3 + if node.name == "feedlot:milker" then + radius = 5 + if inv:is_empty("bucket") then + return false + end + else + if inv:is_empty("main") then + return false + end + end + + local objs = minetest.get_objects_inside_radius(pos, radius) + for _,obj in ipairs(objs) do + ent = obj:get_luaentity() + if not obj:is_player() and obj:get_armor_groups().fleshy and obj:get_armor_groups().fleshy > 0 and is_mob(obj) then + if ent.on_rightclick then + if not (ent.horny and node.name == "feedlot:feedlot") then + if node.name == "feedlot:milker" and not inv:room_for_item("main", "mobs:bucket_milk") then + return false + end + obj:get_luaentity():on_rightclick(fake_player) + end + end + end + end + return true +end + + minetest.register_node("feedlot:feedlot", { description = "Feedlot", tiles = { @@ -126,6 +180,12 @@ minetest.register_node("feedlot:feedlot", { {-0.4375, -0.5, -0.4375, 0.4375, -0.375, 0.4375}, -- NodeBox10 } }, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + start_timer(pos) + end, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + start_timer(pos) + end, allow_metadata_inventory_put = function (_, _, _, stack, _) if stack:get_name() == "bucket:bucket_empty" then return 0 @@ -136,7 +196,8 @@ minetest.register_node("feedlot:feedlot", { on_construct = on_construct, can_dig = can_dig, groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1}, - tube = tube + tube = tube, + on_timer = feed_animals }) minetest.register_node("feedlot:milker", { description = "Milker", @@ -162,43 +223,20 @@ minetest.register_node("feedlot:milker", { on_construct = on_construct, can_dig = can_dig, groups = {snappy = 3, tubedevice = 1, tubedevice_receiver = 1}, - tube = tube -}) - + tube = tube, + on_timer = feed_animals, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + start_timer(pos) + end, + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + start_timer(pos) + end, +}) -local function is_mob(obj) - return obj.get_luaentity and obj:get_luaentity().name and string.sub(obj:get_luaentity().name,1,string.len("mob"))=="mob" -end -minetest.register_abm({ - label = "Feeding and milking", - nodenames = {"feedlot:feedlot", "feedlot:milker"}, - interval = 5, - chance = 1, - action = function (pos, node) - local fake_player = feedlotFakePlayer.create(pos, "fake_player") - local radius = 3 - if node.name == "feedlot:milker" then - radius = 5 - end - local objs = minetest.get_objects_inside_radius(pos, radius) - for _,obj in ipairs(objs) do - ent = obj:get_luaentity() - if not obj:is_player() and obj:get_armor_groups().fleshy and obj:get_armor_groups().fleshy > 0 and is_mob(obj) then - if ent.on_rightclick then - if ent.horny and node.name == "feedlot:feedlot" then - return - end - obj:get_luaentity():on_rightclick(fake_player) - end --- minetest.chat_send_all("animal fed") - end - end - end, -}) minetest.register_craft({ output = "feedlot:feedlot", -- cgit v1.2.3