Switch to Nodetimers, Enable shift+click
authorGabriel Pérez-Cerezo <gabriel@gpcf.eu>
Tue, 10 Mar 2020 21:37:59 +0000 (22:37 +0100)
committerGabriel Pérez-Cerezo <gabriel@gpcf.eu>
Tue, 10 Mar 2020 21:37:59 +0000 (22:37 +0100)
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

index a99b757..b5426ab 100644 (file)
--- 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",