diff --git a/patrol.lua b/patrol.lua index 469e874..7ad8948 100644 --- a/patrol.lua +++ b/patrol.lua @@ -1,5 +1,6 @@ local abs = math.abs +guards.door_close_delay = 5 guards.get_walkable_pos = function(pos, dist) local destpos @@ -93,6 +94,51 @@ guards.get_face_direction = function(self, p1, p2) end +-- try opening a door, gate or hatch via right-click +guards.try_open_door = function(self, pos, closing_again) + if(not(pos)) then + return false + end + local node = minetest.get_node(pos) + -- no suitable node found + if(not(node) or not(node.name) or not(minetest.registered_nodes[node.name])) then + return false + end + -- something that we (guards) might be able to open by right-clicking? + + -- is it a door? + if(doors.registered_doors[node.name]) then + doors.door_toggle(pos, node, nil) --, clicker) + -- is it a normal trapdoor? + elseif(doors.registered_trapdoors[node.name]) then + doors.trapdoor_toggle(pos, node, nil) --, clicker) + -- is it something else that can be right-clicked? + elseif(minetest.registered_nodes[node.name] + and minetest.registered_nodes[node.name].on_rightclick) then +-- and minetest.registered_nodes[node.name].on_rightclick(pos, node, nil)) then + -- guards can't read texts in formspecs + local meta = minetest.get_meta(pos) + if(meta and meta:get_string("formspec") and meta:get_string("formspec") ~= "") then + return false + end + -- do not right-click nodes that have an inventory (they most likely show a + -- formspec - which the NPC can't use anyway) + local inv = meta:get_inventory() + for k, l in pairs(inv:get_lists()) do + return false + end + minetest.registered_nodes[node.name].on_rightclick(pos, node, nil) + else + return false + end + -- close it again after passing through + if(not(closing_again)) then + minetest.after(guards.door_close_delay, guards.try_open_door, self, pos, true) + end + return true +end + + guards.on_step = function(self, dtime, moveresult) if(self.order ~= "patrol" or self.state == "attack") then return true @@ -129,23 +175,37 @@ guards.on_step = function(self, dtime, moveresult) if self.path_stuck_timer > 5.0 then local coll_node = 0 local coll_obj = 0 + local coll_txt = "" + local did_rightclick = false if(moveresult and moveresult.collisions and #moveresult.collisions > 1) then for i, v in ipairs(moveresult.collisions) do if(v.type and v.type == "object") then coll_obj = coll_obj + 1 + coll_txt = coll_txt.." "..tostring(v.object.name) elseif(v.type and v.type == "node") then coll_node = coll_node + 1 + coll_txt = coll_txt.." "..minetest.pos_to_string(v.node_pos) + local n = minetest.get_node(v.node_pos) + if(n and n.name) then + coll_txt = coll_txt.."-"..tostring(n.name) + end + -- if it's a door: wait a bit/try again + did_rightclick = guards.try_open_door(self, v.node_pos, false) end end end minetest.chat_send_player("singleplayer", "I'm stuck! Searching new path.".. - " Objects: "..tostring(coll_obj).." Nodes: "..tostring(coll_node)) + " Objects: "..tostring(coll_obj).." Nodes: "..tostring(coll_node).. + " Details: "..tostring(coll_txt)) + if(did_rightclick) then + self.path_stuck_timer = 1.0 + else -- if(coll_node > 1) then guards.switch_to_pathfinding(self) -- else ---- minetest.chat_send_player("singleplayer", "I'm stuck! There's something in the way.") -- self.wait_a_bit = 5.0 --- end + end end else -- not stuck - just walking to temporary target